Page:
0002 deepen rules registry
Pages
0001 deepen classification safety auditor
0002 deepen rules registry
0003 prune legacy script shims
0004 decouple rfc codecs from mailbox gateway
0005 collapse workflow into mailbox pipeline
0006 decouple gateway orchestration into pipeline
0007 incremental scan cache and progress feedback
0008 port mailsweep to synchronous rust
0009 retire python baseline and complete rust cutover
0010 automated multi platform forgejo release workflow
ADR 0001 deepen classification safety auditor
ADR 0002 deepen rules registry
ADR 0003 prune legacy script shims
ADR 0004 decouple rfc codecs from mailbox gateway
ADR 0005 collapse workflow into mailbox pipeline
ADR 0006 decouple gateway orchestration into pipeline
ADR 0007 incremental scan cache and progress feedback
ADR 0008 port mailsweep to synchronous rust
ADR 0009 retire python baseline and complete rust cutover
ADR 0010 automated multi platform forgejo release workflow
ADRs
CLI Reference
Domain Context
FAQ
Home
Internals
Python API
Rules Schema
Rust API
No results
1
0002 deepen rules registry
MailSweep Doc Bot edited this page 2026-08-24 02:23:29 +00:00
Table of Contents
2. Deepen Rules Registry into a Domain Module
Date: 2026-08-24
Status
Accepted
Context
MailSweep relies on multi-lingual keyword heuristic rules across 13 European languages to classify emails into safety tiers and clutter actions.
Previously, src/mailsweep/rules.py existed only as procedural functions (load_rules, validate_rules, run_13_language_tests, sync_upstream_rules, audit_language_coverage) with unhandled global side-effects:
load_rulescalledsys.exit(1)on missing files, breaking headless consumption and test isolation.sync_upstream_rulesperformed directurllib.requestnetwork calls and wrote backup files to disk without a testable seam.validate_rulesandrun_13_language_testsprinted directly tostdoutwith uncaptured formatting instead of returning structured models.ClassificationEngineaccepted raw, untypeddictobjects without unified rule validation.
Decision
We deepened the rules governance capability into a domain module:
-
RulesRegistry:- Ingests rules from a
Path, raw dictionary, JSON string, orRuleSet. - Injects
RuleSyncTransportvia constructor (transport: RuleSyncTransport | None = None) to isolate upstream synchronization at an adapter seam. - Provides operations:
load(),validate(),run_language_tests(),audit_coverage(), andsync_upstream().
- Ingests rules from a
-
RuleSet&RulesValidationReport:RuleSet: Typed, immutable domain model encapsulating version, languages, critical patterns, receipt patterns, shipping patterns, marketing patterns, survey patterns, custom domains, property keywords, and RFC provenance.RulesValidationReport: Immutable report model encapsulating schema verification results, compiled pattern counts, fixture execution counts (passed_count,total_tests), failure lists, and decoupled.render_text()output.
-
RuleSyncTransport(Seam & Adapters):- Protocol defining
fetch_rules(source_url: str) -> dict[str, Any]. HttpRuleSyncTransport: Production adapter using standard libraryurllib.request.FakeRuleSyncTransport: In-memory test stand-in returning predetermined rule payloads or simulating network failure modes.
- Protocol defining
-
Integration with
ClassificationEngine:ClassificationEngineacceptsRuleSet | RulesRegistry | Mapping[str, Any] | None.
Consequences
- Rule lifecycle, schema validation, and synchronization are isolated with pure in-memory testability.
- No network requests or
sys.exitcalls during automated testing. - Full backwards compatibility retained for existing CLI commands and procedural entrypoints.