This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
7. Incremental Scan Cache, Virtual Folder Exclusion, and Real-Time Progress Feedback
Date: 2026-08-24
Status
Accepted
Context
MailSweep's primary entrypoint (mailsweep sweep / mailsweep scan) scans IMAP mailbox headers to classify clutter and formulate safety-audited cleanup plans.
During full-mailbox scans on large accounts (e.g. 30,000+ messages on Gmail):
- Redundant Virtual Folder Scanning: Default folder discovery scanned Gmail virtual aggregate folders (
\All/[Google Mail]/Kaikki viestit,\Starred,\Important), causing the entire historical email archive to be scanned multiple times. - Stateless Re-Scans: Every execution re-fetched all email headers over IMAP SSL, taking up to 25+ minutes even when zero new emails arrived.
- Lack of Intra-Folder Progress Feedback:
MailboxGateway.fetch_headersfetched UIDs in batches of 100 with zero progress callbacks until an entire folder completed, leading users to believe the CLI had frozen on large folders.
Decision
We resolved these performance and usability bottlenecks across three layers:
-
RFC 6154 Virtual Folder Exclusion (
src/mailsweep/gateway.py):- Automatically exclude RFC 6154 SPECIAL-USE
\All,\Starred, and\Importantattributes from defaultlist_folders()discovery. - Include a 13-language fallback dictionary (
Kaikki viestit,Alla meddelanden,Alle Nachrichten,Tous les messages, etc.) for servers lacking RFC 6154 attributes. - Retain ability for users to explicitly target virtual folders via
IMAP_FOLDERconfiguration.
- Automatically exclude RFC 6154 SPECIAL-USE
-
Incremental Scan Cache (
src/mailsweep/gateway.py,src/mailsweep/pipeline.py):- Introduce
.mailsweep_cache/scan_cache.jsonstoringScanResultenvelope metadata keyed by folder andUIDVALIDITY. - On scan:
- If folder
UIDVALIDITYmatches cached snapshot, query IMAP only for deltaUID > max_cached_uid. - If
UIDVALIDITYchanges (mailbox re-indexed), invalidate cache for that folder and perform a fresh scan.
- If folder
- Provide
--fresh/--no-cacheCLI arguments to bypass local cache on demand. - Add
.mailsweep_cache/to.gitignore.
- Introduce
-
Intra-Batch Real-Time Progress Reporting (
src/mailsweep/gateway.py,src/mailsweep/cli.py):- Pass batch progress
(stage, current_in_folder, total_in_folder, folder_name)directly fromfetch_headersthroughMailboxGateway.scanandMailboxPipeline.scan. - Implement a zero-dependency in-place terminal updater in
cli.pyusing standard librarysys.stdout.write('\r...')with interactive TTY detection. - Increase default IMAP header batch size from 100 to 500 for a 5x reduction in network roundtrips.
- Pass batch progress
Consequences
- Full mailbox scans on Gmail and large IMAP accounts drop from 25+ minutes to ~1–2 minutes on first run, and < 1 second on subsequent runs.
- CLI provides immediate, real-time feedback with message counts, percentages, and stage indicators.
- MailSweep remains 100% zero-dependency with no external terminal formatting or database libraries.
- All safety guarantees (UIDVALIDITY assertions and backup invariants) remain strictly enforced.