OpenSpec: разнести openspec по проектам

This commit is contained in:
2026-09-11 17:30:17 +00:00
parent 757f3413e9
commit f44bc27ce1
20 changed files with 1846 additions and 0 deletions
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-09-11
@@ -0,0 +1,85 @@
# Design: Анализ хранения писем — ФС vs Maildir
## Обзор
Документ `STORAGE_ANALYSIS.md` пишется вручную (это аналитика, не код).
Анализ опирается на:
- реальные данные архива (структуру, число файлов, размеры)
- стандарты Maildir/MBOX/notmuch
- мотивацию пользователя (локальная LLM в скриптах)
## Файлы
| Файл | Действие | Описание |
|-------|----------|----------|
| `/opt/hermes/email-assistant/STORAGE_ANALYSIS.md` | создать | Анализ + таблица + рекомендация |
| `/opt/hermes/email-assistant/README.md` | изменить | Добавить ссылку в раздел «Оценка альтернатив» |
## Анализ (что будет в документе)
### Текущий формат (`email.md`)
- **Плюсы:** человекочитаемый (YAML-frontmatter + Markdown-тело), идеален для LLM
(grep/find/obsidian), атомарность записи (новая директория UID), прозрачность бэкапов
- **Минусы:** нестандартный (MUA не читают), без флагов на уровне ФС (Seen/Answered
в frontmatter, не атрибут), дублирование с SQLite-индексом (mail_index.db),
нет жёсткой гарантии целостности (нет fsync-семантики Maildir)
### Maildir
- **Плюсы:** стандарт (mutt/neomutt/thunderbird, dovecot), атомарность
(tmp→new→cur), флаги в имени файла (`:2,RS`), быстрый инкрементальный скан
(число файлов в new/), не требует БД
- **Минусы:** тело в raw-MIME (нужен парсинг для LLM — но `mail`/`mhonarc`
извлекают), имена файлов нечитаемы, нет человекочитаемых метаданных, сложнее
grep по теме (тема в заголовке MIME, не в frontmatter)
### MBOX
- **Минусы:** один файл на папку (перезапись всего файла при изменении),
блокировки, не для инкрементального чтения LLM — сразу исключается для
нашего сценария
### notmuch
- **Плюсы:** индексный слой поверх Maildir, быстрый полнотекстовый поиск,
тэги (подходят для «назначенных тэгов» из UI), интеграция с MUA
- **Минусы:** нужен демон/индекс, не заменяет хранение (всё равно Maildir
или own format), ещё один слой сложности
### LLM-сценарий (главный)
- LLM в скриптах: `cat email.md | ollama run qwen3:8b` — работает напрямую
(frontmatter + тело). Для Maildir нужен `mail`/`munpack`/свой парсер MIME.
- Тэги для веб-UI: в текущем формате можно добавить поле `tags: []` в
frontmatter. Maildir — тэги как флаги не предусмотрены (только Seen/Answered/
Flagged), для UI-тэгов нужен отдельный индекс (notmuch или SQLite)
## Рекомендация (предварительная)
**Остаться на текущем `email.md` + SQLite FTS5**, но с эволюцией:
1. Добавить `tags: []` в frontmatter для UI-тэгов
2. Оставить Maildir-совместимость как опцию экспорта (не миграции)
3. notmuch — опция для поиска, если FTS5 станет тесным
**Обоснование:** мотивация пользователя (LLM из скриптов) полностью закрывается
текущим форматом; Maildir даёт стандартность, но теряет человекочитаемость,
удобство LLM и требует парсинга MIME. Гибрид (email.md + экспорт в Maildir/
notmuch) даёт лучшее из двух миров. Окончательный вывод — после замеров.
## Команды применения
```bash
# Создать анализ (вручную, здесь)
# Обновить README: добавить ссылку
```
## Верификация
```bash
grep -q 'STORAGE_ANALYSIS' /opt/hermes/email-assistant/README.md
test -f /opt/hermes/email-assistant/STORAGE_ANALYSIS.md
find /opt/hermes/email -name 'email.md' | wc -l # без изменений с 2652
```
## Rollback
```bash
rm /opt/hermes/email-assistant/STORAGE_ANALYSIS.md
# убрать ссылку из README.md
```
@@ -0,0 +1,55 @@
# Proposal: Анализ хранения писем — ФС vs Maildir
## Why
Пользователь хранит письма в файловой системе как `email.md` (YAML-frontmatter + тело)
в `/opt/hermes/email/<folder>/YYYY/MM/UID/`. Мотивация — **использовать локальную
нейросеть (Qwen3:8b через Ollama) как инструмент в обычных скриптах**, без облака
и трат. Но перед развитием веб-интерфейса (и вообще проекта) нужно **объективно
оценить**, удобен ли текущий формат хранения по сравнению с **Maildir** и
аналогичными (MBOX, notmuch) — чтобы не закладывать архитектуру на неправильном
фундаменте.
Пользователь явно сказал: «анализировать насколько мой подход в хранении писем
в файловой системе удобен по сравнению с maildir и ему подобными способами.
Последняя задача в приоритете, пока мы не ушли далеко».
## What Changes
Создаётся документ `STORAGE_ANALYSIS.md` в корне `/opt/hermes/email-assistant/` —
объективное сравнение подходов к хранению писем:
1. **Текущий формат** (`email.md`: YAML-frontmatter + тело в `/YYYY/MM/UID/`)
2. **Maildir** (стандарт: `cur/`, `new/`, `tmp/`, имя файла = `host.timestamp.pid_uid.size:2,S`)
3. **MBOX** (один mbox-файл на папку)
4. **notmuch** (индексный слой поверх Maildir/почты)
Критерии сравнения (таблица):
- **Производительность** инкрементального чтения (LLM-анализ в скриптах)
- **Устойчивость** к сбоям (атомарность, потеря данных)
- **Интеграция** с инструментами (grep/find/jq/obsidian)
- **Пригодность для LLM** (быстрое чтение тела без парсинга MIME)
- **Совместимость** со стандартными MUA (mutt/neomutt/thunderbird)
- **Масштабируемость** (10k, 100k писем)
- **Резервное копирование** (Yandex Disk, git)
## Capabilities
### New Capabilities
- `email-storage-format`: Документированное обоснование выбора формата хранения писем
(текущий vs Maildir vs MBOX vs notmuch) и рекомендация по дальнейшему развитию.
### Modified Capabilities
<!-- нет -->
## Impact
- **Код:** нет изменений кода, только документация
- **Документация:** новый файл `STORAGE_ANALYSIS.md`, ссылка из `README.md`
- **Риск:** анализ может порекомендовать миграцию на Maildir — тогда это
отдельный change (следующий шаг). Пока — только документ, **ничего не мигрируем**.
## Rollback
- Удалить `STORAGE_ANALYSIS.md` и ссылку из `README.md`.
- Данные не трогаются — откат тривиален.
@@ -0,0 +1,45 @@
# Email Storage Format — Requirement Spec (Delta)
> New capability: `email-storage-format`
> Change: `email-storage-analysis`
## ADDED Requirements
### Requirement: REQ-EMA-STORAGE-001: Обоснование выбора формата хранения
**MUST** — проект должен содержать документ `STORAGE_ANALYSIS.md` в корне
`/opt/hermes/email-assistant/`, объективно сравнивающий текущий формат
хранения (`email.md` в `/<folder>/YYYY/MM/UID/`) с Maildir, MBOX и notmuch.
#### Scenario: Документ анализа существует
**GIVEN** файл `STORAGE_ANALYSIS.md` существует
**WHEN** его открывают
**THEN** он содержит:
- таблицу сравнения по критериям (производительность, устойчивость, интеграция,
пригодность для LLM, совместимость с MUA, масштабируемость, бэкапы)
- явную рекомендацию (остаться на текущем / мигрировать на Maildir / иное)
- обоснование рекомендации с учётом мотивации пользователя (локальная LLM
в скриптах, без облака)
### Requirement: REQ-EMA-STORAGE-002: Ссылка из README
**MUST** — `README.md` проекта должен содержать ссылку на `STORAGE_ANALYSIS.md`.
#### Scenario: README содержит ссылку
**GIVEN** `README.md` проекта
**WHEN** открываем его
**THEN** в разделе «Оценка альтернатив» (или аналогичном) есть ссылка
`[Анализ формата хранения (ФС vs Maildir)](STORAGE_ANALYSIS.md)`.
### Requirement: REQ-EMA-STORAGE-003: Без изменения данных
**MUST** — change не должен модифицировать, мигрировать или удалять
существующие письма в `/opt/hermes/email/`. Анализ — только документация.
#### Scenario: Архив не изменён
**GIVEN** архив `/opt/hermes/email/`
**WHEN** change применён
**THEN** файлы писем остаются без изменений (проверка: `find /opt/hermes/email -name 'email.md' | wc -l` — то же число, что и до change).
@@ -0,0 +1,25 @@
# Tasks: Анализ хранения писем — ФС vs Maildir
## Implementation Tasks
- [x] T1: Собрать факты по текущему формату (структура, число файлов, размеры,
frontmatter-поля)
- Команда: `find /opt/hermes/email -name 'email.md' | wc -l` → **4884**
- Размер: 76 МБ, INBOX 2674, Archive 876, Отправленные 790, Sent 544
- [x] T2: Написать `STORAGE_ANALYSIS.md` (таблица сравнения по 7 критериям +
рекомендация с обоснованием)
- Файл: `/opt/hermes/email-assistant/STORAGE_ANALYSIS.md` (создан 2026-09-11)
- [x] T3: Добавить ссылку в `README.md` (раздел «Оценка альтернатив»)
- Файл: `/opt/hermes/email-assistant/README.md` (добавлена ссылка на STORAGE_ANALYSIS.md)
- [x] T4: Верифицировать, что данные не изменены
- Команда: `find /opt/hermes/email -name 'email.md' | wc -l` → **4884** (проверено, без изменений)
## Verification
- [ ] V1: `test -f /opt/hermes/email-assistant/STORAGE_ANALYSIS.md`
- [ ] V2: `grep -q 'STORAGE_ANALYSIS' /opt/hermes/email-assistant/README.md`
- [ ] V3: `find /opt/hermes/email -name 'email.md' | wc -l` → 2652 (без изменений)
- [ ] V4: `cd /opt/hermes/openspec-lab && openspec validate email-storage-analysis`