From e31b5f2552a2284246751ce83481f02732345746 Mon Sep 17 00:00:00 2001 From: hermes Date: Fri, 11 Sep 2026 13:13:21 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=B0=D0=BD=D0=B0=D0=BB=D0=B8=D0=B7=20?= =?UTF-8?q?=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B0=20=D1=85=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=A4=D0=A1=20vs=20Maildir=20?= =?UTF-8?q?(=D0=B7=D0=B0=D0=B4=D0=B0=D1=87=D0=B0=204)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - STORAGE_ANALYSIS.md: сравнение email.md / Maildir / MBOX / notmuch по 7 критериям; рекомендация — остаться на email.md + добавить tags в frontmatter + опциональный экспорт в Maildir - README.md: ссылка на анализ в разделе «Оценка альтернатив» - Данные не изменены (4884 email.md до и после) --- README.md | 3 +- STORAGE_ANALYSIS.md | 151 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 STORAGE_ANALYSIS.md diff --git a/README.md b/README.md index 423cb36..dcb8ff6 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,5 @@ ## Оценка альтернатив -- [Анализ Nylas CLI](NYLAS_ANALYSIS.md) — почему Nylas **не подходит** для локального архива (2026-09-11) \ No newline at end of file +- [Анализ Nylas CLI](NYLAS_ANALYSIS.md) — почему Nylas **не подходит** для локального архива (2026-09-11) +- [Анализ формата хранения: ФС vs Maildir](STORAGE_ANALYSIS.md) — почему текущий формат удобнее Maildir для локальной LLM (2026-09-11) \ No newline at end of file diff --git a/STORAGE_ANALYSIS.md b/STORAGE_ANALYSIS.md new file mode 100644 index 0000000..3c94a8b --- /dev/null +++ b/STORAGE_ANALYSIS.md @@ -0,0 +1,151 @@ +# Анализ хранения писем: Файловая система 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) \ No newline at end of file