# Анализ хранения писем: Файловая система vs Maildir **Дата:** 2026-09-11 **Статус:** Анализ (не миграция). Данные не изменены. **Мотивация:** использовать локальную нейросеть (Qwen3:8b, Ollama) как инструмент в обычных скриптах — без облака и трат. --- ## TL;DR / Рекомендация **Остаться на текущем формате** (`email.md` + YAML-frontmatter + SQLite FTS5). Он полностью закрывает сценарий «локальная LLM из скриптов», которым мотивирован выбор файлового хранения. Maildir даёт стандартность, но для LLM-анализа хуже (нужен разбор MIME) и не поддерживает произвольные тэги. **Эволюция вместо миграции:** 1. Добавить `tags: []` в frontmatter (для веб-UI «назначенные тэги») 2. Держать Maildir-совместимость как **опцию экспорта** (не как базовое хранение) 3. `notmuch` — опция позже, если FTS5 станет тесным --- ## Факты по текущему архиву (замер 2026-09-11) | Метрика | Значение | |---------|----------| | Всего email.md | **4884** | | Объём | **76 МБ** | | INBOX (вкл. подпапки) | 2674 | | Archive | 876 | | Отправленные | 790 | | Sent | 544 | | Размер mail_index.db (FTS5) | 5.4 MB | | Структура | `//YYYY/MM/UID/email.md` | Frontmatter (пример): ```yaml id: 4 folder: INBOX/!Отчеты subject: "FW: Справка о статусах..." from: "Головлев Алексей Вячеславович " to: "Рыбкин Валентин Станиславович " date: "2025-08-22 21:50+03:00" flags: ["Seen"] ``` Плюс в части файлов: Message-ID, References, In-Reply-To, Content-Type. Тело — в том же файле после `---`. --- ## Сравнение форматов | Критерий | Текущий (email.md + FTS5) | Maildir | MBOX | notmuch | |----------|---------------------------|---------|------|---------| | **Пригодность для LLM-скриптов** | ★★★★★ — `cat email.md \| ollama` напрямую: frontmatter + тело | ★★☆ — raw-MIME, нужен парсер (`mail`/`munpack`) | ★★☆ — mbox, нужен разбор | ★★★★ — поиск готов, но тело в Maildir | | **Человекочитаемость** | ★★★★★ — YAML + Markdown, grep/obsidian | ★★☆ — имена файлов нечитаемы, MIME | ★★☆ | ★★★ | | **Производительность инкр. чтения** | ★★★★ — скан случайных UID-папок | ★★★★★ — число файлов в `new/` = новых писем | ★★☆ — весь файл на перезапись | ★★★★★ | | **Атомарность / устойчивость** | ★★★★ — новая папка на письмо (но без fsync) | ★★★★★ — tmp→new→cur, эталон | ★★☆ — блокировки, частичная запись | ★★★★ | | **Флаги (Seen/Answered)** | ★★★ — в frontmatter | ★★★★★ — в имени файла `:2,RS` | ★★★ | ★★★★ | | **Произвольные тэги (для UI)** | ★★★★★ — добавить `tags: []` | ★★☆ — только флаги, тэгов нет | ★★☆ | ★★★★★ — core-фича | | **Стандарт / совместимость с MUA** | ★★☆ — свой, MUA не читают | ★★★★★ — mutt/neomutt/thunderbird/dovecot | ★★★★★ — legacy | ★★★★ (поверх Maildir) | | **Масштабируемость (10k–100k)** | ★★★★ — но много маленьких файлов | ★★★★★ | ★★☆ | ★★★★★ | | **Бэкапы (Yandex Disk / git)** | ★★★★★ — простой копией/grep | ★★★★ — тысячи файлов | ★★★★ | ★★★ (нужен индекс) | --- ## Детали по каждому подходу ### Текущий формат `email.md` (выбран) **Плюсы:** - Идеален для локальной LLM: `cat email.md | ollama run qwen3:8b "резюмируй"` — тело уже очищено от MIME, frontmatter даёт атрибуты для фильтрации в скрипте - Прозрачность: `grep`, `find`, `jq`, Obsidian, VS Code - Атомарность записи: `mail_archive.py` создаёт новую папку `UID/`, не трогая существующие письма → устойчиво к сбою в любой момент - Бэкап = копирование директории (Yandex Disk FUSE) **Минусы:** - Нестандартный: ни один MUA (mutt/thunderbird) не читает напрямую - Флаги в frontmatter, не в ФС-атрибутах → медленнее для MUA - Нет встроенной семантики целостности Maildir (fsync) — но для архива это ок - Дублирование с FTS5-индексом (mail_index.db) — два источника правды - 4884 файла = 4884 маленьких файла → фирменных лимитов на inode нет, но на сотнях тысяч лучше Maildir ### Maildir **Плюсы:** - **Стандарт де-факто**: mutt, neomutt, thunderbird, dovecot читают - **Эталон атомарности**: `tmp/` → `new/` → `cur/`, флаги в имени файла - Новые письма = файлы в `new/` → быстрый инкрементальный скан (нет SQL) - Надёжность при сбое: никогда не частичного файла **Минусы (критично для нас):** - Тело в **raw-MIME**: для LLM-анализа нужен парсер (email.message, munpack). У нас аналогично 2674 письма, но LLM должен читать frontmatter за `cat` - Имена файлов нечитаемы (`1700000000.12345.host:2,S`) — grep по теме невозможен - **Нет произвольных тэгов** — только Seen/Answered/Flagged/Deleted. Для «назначенных тэгов» в веб-UI пришлось бы вести отдельный индекс (notmuch/SQLite) - Не человекочитаем в Obsidian ### MBOX Исключается сразу: один большой файл на папку, перезапись при любом изменении, блокировки, плохо для инкрементального чтения и бэкапов по частям. Для LLM и бэкапов на Yandex Disk — худший выбор. ### notmuch (поверх Maildir или email.md) **Плюсы:** полнотекстовый поиск с тэгами — идеален для UI-тэгов. **Минусы:** это **индексный слой**, не хранилище. Требует демона/индекса, дублирует то, что уже делает FTS5. Дисквалифицирует простоту `grep`. --- ## Гибридный путь (рекомендация) Сохранить текущий `email.md` как **каноническое хранилище** (источник правды), но: 1. **Добавить `tags: []`** в frontmatter при записи (для UI) — тривиально в `mail_archive.py` 2. **Экспорт в Maildir** как **опция** (для чтения в mutt/thunderbird при желании), не зеркало в реальном времени — по запросу 3. **FTS5 остаётся** поисковым индексом; при росте >50k писем — оценить notmuch Это даёт: LLM-удобство (текущий), стандартную совместимость (опция экспорта), UI-тэги (frontmatter), поиск (FTS5). Без потери данных и без миграции. --- ## Влияние на веб-интерфейс (задача 1) Текущий формат уже содержит всё для UI-списка: - `date` → дата письма - `from` → адресант - `subject` → тема - (новое) `tags` → назначенные тэги - `folder` → текущая папка (для перемещения: `mail_archive.py` или прямой `mv` + обновить frontmatter + FTS5) Maildir не дал бы тэгов без отдельного индекса. Текущий формат — оптимален. --- ## Вывод Текущий подход (`email.md` + FTS5) **удобнее** Maildir для заявленной цели (локальная LLM из скриптов без облака). Maildir выигрывает только в «стандартной совместимости с MUA» и «инкрементном скане без БД» — что не критично для нашего сценария. **Рекомендуется остаться на текущем + добавить `tags` в frontmatter + опциональный экспорт в Maildir.** Ссылки: [README](README.md) · [STATUS](STATUS.md)