AI spam classification: the model's opinion as one bounded spam signal, and the llm_prompt Sieve function (AI-1 to AI-28)
The classifier sends only the subject and text, between unforgeable markers after the operator's prompt, to an OpenAI-compatible endpoint the operator configured; nothing is preset. Its answer maps to an LLM_ tag whose score is clamped (+5.0, -1.0 by default) and can never discard or reject on its own; X-Spam-LLM is sanitized, encoded and folded, and a planted one is removed. Failures, timeouts past the ceiling, a full slot or a paused model leave mail flowing untagged. llm_prompt answers trusted scripts, and accounts holding interactAi within an hourly limit. Redirects aren't followed and no content or secret is logged. The limits live in inbuxa:AiLimits. Acceptance tests 1 and 3 to 21; test 2 as the re-enabled shared llm case, whose setup no longer waits on a rules file from a developer's own path; test 22 written as the ignored ai_compat.
This commit is contained in:
+1
-1
@@ -279,7 +279,7 @@ is written.
|
||||
| 2 | Masked email | Per-sender disposable addresses that deliver to the account | Existing addresses must keep delivering (§3.4). Built 2026-09-18 in `crates/features`; status in `features/masked-email.md`. |
|
||||
| 3 | Undelete | Deleted mail held for a set period and restorable | Existing archived items must stay restorable. Built 2026-09-18 in `crates/features`; status in `features/undelete.md`. |
|
||||
| 4 | Branding and templates | Operator logo, and the text of calendar alarm and invitation emails | INBUXA's branding is the default. Built 2026-09-18 in `crates/features`; status in `features/branding-and-templates.md`. |
|
||||
| 5 | AI spam classification | An optional model's opinion as one spam signal, and a Sieve function that asks a model | Local and auditable model only: no hosted API by default. Spec: `features/ai-spam-classification.md`. |
|
||||
| 5 | AI spam classification | An optional model's opinion as one spam signal, and a Sieve function that asks a model | Local and auditable model only: no hosted API by default. Built 2026-09-19 in `crates/features`; status in `features/ai-spam-classification.md`. |
|
||||
| 6 | Monitoring history, live tracing, alerts | Stored metrics and traces, a live trace view, and threshold alerts | ihasmail's dashboard shows them. Spec: `features/monitoring.md`. |
|
||||
| 7 | SCIM 2.0 provisioning | Accounts and groups managed by an identity provider | From RFC 7643 and RFC 7644. The largest piece. Spec: `features/scim.md`. |
|
||||
| 8 | Scale-out storage | SQL read replicas; sharded blob and in-memory stores | For large installs only. Spec: `features/scale-out-storage.md`. |
|
||||
|
||||
@@ -470,6 +470,37 @@ Not for observation, but open:
|
||||
10. ~~The name of the fork's limits singleton.~~ Settled 2026-09-18:
|
||||
`inbuxa:AiLimits` (see "Added by inbuxa-server").
|
||||
|
||||
## Implementation status
|
||||
|
||||
Built 2026-09-19 from this spec, clean-room, under the multi-tenancy hand-off
|
||||
brief's rules. The rules live in `crates/features` (`inbuxa-features`, module
|
||||
`ai`); the model call in `crates/common/src/enterprise/llm.rs`, at the path
|
||||
the shared tests name; the classifier step in
|
||||
`crates/spam-filter/src/analysis/llm.rs`; `inbuxa:AiLimits` in
|
||||
`crates/jmap/src/inbuxa/ai_limits.rs`; upstream files carry hooks marked
|
||||
`inbuxa:`. Acceptance tests 1 and 3 to 21 pass as `tests/src/system/ai.rs`,
|
||||
against a stub model on loopback. Test 2 passes as the shared `llm` case in
|
||||
`tests/src/smtp/inbound/antispam.rs`, re-enabled with its mock reading the
|
||||
last message.
|
||||
|
||||
- **AI-1 to AI-28:** built.
|
||||
- **Test 22 (compat)** is written as `ai_compat`, ignored, and unrun until a
|
||||
copy of INBUXA's data is provided. It checks the twelve `LLM_*` tags and
|
||||
scores in observed 2.
|
||||
- **No model is calibrated.** The code speaks the OpenAI-compatible API and
|
||||
has only met stubs. How well a given local model follows the default
|
||||
prompt, and how accurate it is, isn't measured yet.
|
||||
- **Known limits, not requirements of this spec:**
|
||||
- The call limits (AI-10, AI-11, AI-24) are per server node, as the spec
|
||||
says; a cluster of n nodes can have n times `maxConcurrentCalls` in
|
||||
flight.
|
||||
- The shared antispam suite's setup reads spam rules from a developer's own
|
||||
checkout path. It now carries on when that file is missing (a test-only
|
||||
change marked `inbuxa:`), so its `llm` case runs; its other cases still
|
||||
need the rules file.
|
||||
- Test 21's warning count is checked only when `registry.build-warning` is
|
||||
a metric of interest; the warning itself is always logged.
|
||||
|
||||
## Observed
|
||||
|
||||
Settled on 2026-09-18 against INBUXA's live Enterprise server (Stalwart
|
||||
|
||||
Reference in New Issue
Block a user