1 0002 deepen rules registry
MailSweep Doc Bot edited this page 2026-08-24 02:23:29 +00:00

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:

  1. load_rules called sys.exit(1) on missing files, breaking headless consumption and test isolation.
  2. sync_upstream_rules performed direct urllib.request network calls and wrote backup files to disk without a testable seam.
  3. validate_rules and run_13_language_tests printed directly to stdout with uncaptured formatting instead of returning structured models.
  4. ClassificationEngine accepted raw, untyped dict objects without unified rule validation.

Decision

We deepened the rules governance capability into a domain module:

  1. RulesRegistry:

    • Ingests rules from a Path, raw dictionary, JSON string, or RuleSet.
    • Injects RuleSyncTransport via constructor (transport: RuleSyncTransport | None = None) to isolate upstream synchronization at an adapter seam.
    • Provides operations: load(), validate(), run_language_tests(), audit_coverage(), and sync_upstream().
  2. 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.
  3. RuleSyncTransport (Seam & Adapters):

    • Protocol defining fetch_rules(source_url: str) -> dict[str, Any].
    • HttpRuleSyncTransport: Production adapter using standard library urllib.request.
    • FakeRuleSyncTransport: In-memory test stand-in returning predetermined rule payloads or simulating network failure modes.
  4. Integration with ClassificationEngine:

    • ClassificationEngine accepts RuleSet | RulesRegistry | Mapping[str, Any] | None.

Consequences

  • Rule lifecycle, schema validation, and synchronization are isolated with pure in-memory testability.
  • No network requests or sys.exit calls during automated testing.
  • Full backwards compatibility retained for existing CLI commands and procedural entrypoints.