mirror of
https://gitverse.ru/kpa39l/openspec-lab.git
synced 2026-09-28 21:05:02 +00:00
change email-storage-analysis: ФС vs Maildir анализ (задача 4)
- STORAGE_ANALYSIS.md: сравнение email.md/Maildir/MBOX/notmuch, рекомендация остаться на email.md + tags в frontmatter + опц. экспорт Maildir - 3 REQUIREMENTS в spec email-storage-format, change архивирован - Задача 4 из портфеля веб-UI закрыта
This commit is contained in:
@@ -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`.
|
||||
- Данные не трогаются — откат тривиален.
|
||||
+45
@@ -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`
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-09-08
|
||||
@@ -0,0 +1,65 @@
|
||||
# Design — icq-fix-prosody-network
|
||||
|
||||
## Итоговая команда
|
||||
|
||||
```bash
|
||||
cd /opt/icq && docker compose up -d --force-recreate prosody
|
||||
```
|
||||
|
||||
Docker compose пересоздаст контейнер `icq-prosody` из того же образа
|
||||
(`gitea.nixg.ru/hermes/icq-prosody:13.0`) с теми же volume'ами и подключит его
|
||||
к сети `icq_default` (как указано в docker-compose.yml). После этого webchat
|
||||
и slidgram снова видят prosody по имени `icq-prosody`.
|
||||
|
||||
Образ не меняется (config-hash из inspect = 6523667b1cb848380db7b2b77c15d3d1d0beeb303c8d03de2646699012672f85 —
|
||||
тот же compose-проект icq). Данные на volume'ах `./data`, `./config`, `./certs`,
|
||||
`./modules`, `./logs` — не затрагиваются.
|
||||
|
||||
## Порядок
|
||||
|
||||
1. **Снимок состояния ДО** (для сравнения):
|
||||
- `docker ps --format '{{.Names}} {{.Networks}}'` — зафиксировать пустую сеть у prosody.
|
||||
- `docker network inspect icq_default` — зафиксировать состав (webchat, slidgram).
|
||||
2. **Пересоздание:**
|
||||
- `cd /opt/icq && docker compose up -d --force-recreate prosody`
|
||||
- дождаться `Started` и статуса `Up`.
|
||||
3. **Проверка сети (изнутри compose):**
|
||||
- `docker ps --format '{{.Names}} {{.Networks}}'` → prosody в icq_default.
|
||||
- `docker network inspect icq_default` → prosody с IP.
|
||||
- `docker exec icq-prosody hostname -i` → непустой IP.
|
||||
- `docker exec icq-webchat getent hosts icq-prosody` → резолвится в 172.27.0.x.
|
||||
4. **Проверка приложения:**
|
||||
- `curl -i` к BOSH/WS через nginx/Caddy на 5280, проверить, что веб-клиент
|
||||
получает ответ (VirtualHost nixg.ru + consider_websocket_secure=true уже в конфиге).
|
||||
- `docker logs icq-prosody --tail 100` — нет новых ошибок, компонент
|
||||
telegram.nixg.ru аутентифицирован.
|
||||
- `docker logs icq-webchat --tail 50` — nginx отдаёт страницу без ошибок.
|
||||
- `docker logs icq-slidgram --tail 50` — мост без ошибок аутентификации.
|
||||
5. **Проверка снаружи:**
|
||||
- `curl -i https://chat.nixg.ru/` через Caddy → 200.
|
||||
- WS: `curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" ...` на
|
||||
wss://xmpp.nixg.ru (или через браузер/логи) → HTTP 101.
|
||||
|
||||
## Откат
|
||||
|
||||
Если после пересоздания что-то пошло не так (маловероятно — конфиг/образ не менялись):
|
||||
|
||||
```bash
|
||||
cd /opt/icq && docker compose up -d # повторное создание без force
|
||||
# или, если совсем плохо:
|
||||
docker start icq-prosody # старый контейнер ещё существует до пересоздания
|
||||
```
|
||||
|
||||
Volume'ы не трогаем; данные не теряются. Резервная копия текущего состояния:
|
||||
`docker inspect icq-prosody > /tmp/icq-prosody-inspect-before.json` (снимок до пересоздания).
|
||||
|
||||
## Затронутые файлы
|
||||
|
||||
Не меняем ни одного файла конфигурации. Только состояние Docker (контейнер).
|
||||
|
||||
## Затрагиваемые сервисы/порты
|
||||
|
||||
- prosody: 5222/5269/5280/5281 (все сохраняются из compose)
|
||||
- webchat: 8081 (nginx, проксируется Caddy на vps02)
|
||||
- slidgram: 5347 (external component)
|
||||
- Сеть: icq_default (172.27.0.0/16, шлюз 172.27.0.1)
|
||||
@@ -0,0 +1,58 @@
|
||||
# Proposal — icq-fix-prosody-network
|
||||
|
||||
## Почему
|
||||
|
||||
С 2026-09-08 chat.nixg.ru (веб-клиент Converse.js) снова показывает бесконечную загрузку.
|
||||
Ручной запуск контейнера prosody не помог.
|
||||
|
||||
**Корневая причина (подтверждена инспекцией):**
|
||||
- Контейнер `icq-prosody` запущен вручную вне docker compose (`docker start`, пересоздан
|
||||
вручную 2026-09-08T13:33) и **не подключён ни к одной Docker-сети**:
|
||||
- `docker ps -a` → колонка Networks у `icq-prosody` пустая;
|
||||
- `docker network inspect icq_default` → в сети только `icq-webchat` (172.27.0.2)
|
||||
и `icq-slidgram` (172.27.0.4), prosody отсутствует;
|
||||
- `docker inspect icq-prosody --format '{{json .NetworkSettings.Networks}}'` → `{}`;
|
||||
- `docker exec icq-prosody hostname -i` → пусто (нет IP в контейнере).
|
||||
- Из-за этого `icq-webchat` не может достучаться до Prosody по имени `icq-prosody`
|
||||
(DNS icq_default не резолвится), WebSocket-соединение не устанавливается →
|
||||
«бесконечная загрузка».
|
||||
- `NetMode=icq_default` в метаданных — обманчиво: метка осталась, но фактического
|
||||
подключения к сети нет (вероятно, контейнер пересоздан вне compose).
|
||||
|
||||
## Что делаем
|
||||
|
||||
Пересоздать `icq-prosody` штатно через docker compose (force-recreate), чтобы он
|
||||
вернулся в сеть `icq_default` вместе с webchat и slidgram. Проверить, что:
|
||||
- контейнер подключён к `icq_default` с IP;
|
||||
- webchat и slidgram видят prosody по имени `icq-prosody`;
|
||||
- chat.nixg.ru снова открывается (WS connect → 101);
|
||||
- мост telegram.nixg.ru по-прежнему аутентифицирован;
|
||||
- после рестарта ничего не сломалось (логотипы, S2S, http_upload).
|
||||
|
||||
## Объём
|
||||
|
||||
Один сервис (`prosody`), одна команда `docker compose up -d --force-recreate prosody`
|
||||
(+ проверки). Без изменений конфигов и образов.
|
||||
|
||||
## Принятые решения
|
||||
|
||||
- Не менять конфиги Prosody, nginx, DNS — только вернуть контейнер в compose-жизненный цикл.
|
||||
- Не трогать данные (./data, ./config, ./logs) — они на volume'ах.
|
||||
- Верификацию делать и изнутри (docker exec), и снаружи (curl через Caddy/nginx).
|
||||
|
||||
## Риски и откат
|
||||
|
||||
- **Риск:** force-recreate может на пару секунд уронить веб-чат/федерацию. Приемлемо.
|
||||
- **Откат:** `docker compose up -d` (пересоздание с теми же volume'ами) или
|
||||
`docker start icq-prosody` если что-то пошло не так — данные не теряются (volume'ы).
|
||||
- **Не трогаем** данные пользователей; никаких удалений.
|
||||
|
||||
## Критерии приёмки
|
||||
|
||||
- [ ] `docker ps` показывает `icq-prosody` в сети `icq_default` (не пустая колонка)
|
||||
- [ ] `docker network inspect icq_default` содержит `icq-prosody` с IP
|
||||
- [ ] `docker exec icq-prosody hostname -i` возвращает IP (не пусто)
|
||||
- [ ] из webchat резолвится и коннектится `icq-prosody:5280`
|
||||
- [ ] https://chat.nixg.ru грузится, Converse показывает окно входа (не бесконечная загрузка)
|
||||
- [ ] WS `wss://xmpp.nixg.ru` → HTTP 101 (переключение протокола)
|
||||
- [ ] `docker logs icq-prosody` без новых ошибок; компонент `telegram.nixg.ru` аутентифицирован
|
||||
@@ -0,0 +1,68 @@
|
||||
# Spec Delta — icq-services
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Жизненный цикл сервисов — только docker compose
|
||||
|
||||
Все сервисы проекта /opt/icq (prosody, webchat, slidgram) управляются исключительно
|
||||
через `docker compose up -d --force-recreate <service>`, а не ручными `docker start`
|
||||
или `docker create`. Каждый сервис подключён к сети `icq_default` и резолвится по
|
||||
имени сервиса (DNS-алиас из compose) внутри этой сети.
|
||||
|
||||
#### Scenario: prosody запущен штатно через compose
|
||||
|
||||
- **GIVEN** сервис prosody пересоздан командой `docker compose up -d --force-recreate prosody`
|
||||
- **WHEN** выполняется `docker ps --format '{{.Names}} {{.Networks}}'`
|
||||
- **THEN** у `icq-prosody` непустая колонка Networks, содержащая `icq_default`
|
||||
|
||||
#### Scenario: prosody подключён к сети icq_default
|
||||
|
||||
- **GIVEN** контейнер prosody в сети icq_default
|
||||
- **WHEN** выполняется `docker network inspect icq_default`
|
||||
- **THEN** в списке контейнеров есть `icq-prosody` с IPv4-адресом из 172.27.0.0/16
|
||||
|
||||
#### Scenario: резолвинг имени из веб-чата
|
||||
|
||||
- **GIVEN** контейнер веб-чата в той же сети
|
||||
- **WHEN** выполняется `docker exec icq-webchat getent hosts icq-prosody`
|
||||
- **THEN** возвращается IP 172.27.0.x (просоди виден из веб-чата)
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Доступность веб-чата chat.nixg.ru
|
||||
|
||||
Контейнер `icq-prosody` имеет IP-адрес в сети `icq_default` и доступен из
|
||||
`icq-webchat` по имени `icq-prosody`; веб-клиент Converse.js подключается к
|
||||
wss://xmpp.nixg.ru без бесконечной загрузки.
|
||||
|
||||
#### Scenario: веб-клиент открывается
|
||||
|
||||
- **GIVEN** prosody в сети icq_default и доступен из webchat
|
||||
- **WHEN** браузер открывает https://chat.nixg.ru
|
||||
- **THEN** страница Converse.js загружается и показывает форму входа
|
||||
(не бесконечная загрузка)
|
||||
|
||||
#### Scenario: WebSocket-сессия устанавливается
|
||||
|
||||
- **GIVEN** веб-клиент открыт
|
||||
- **WHEN** Converse.js соединяется с wss://xmpp.nixg.ru
|
||||
- **THEN** handshake завершается HTTP 101 и появляется форма входа
|
||||
|
||||
### Requirement: Мост Telegram (Slidge)
|
||||
|
||||
Компонент `telegram.nixg.ru` продолжает аутентифицироваться с prosody
|
||||
(external component XEP-0114, порт 5347) после пересоздания prosody; данные моста
|
||||
(./slidgram/data) не затрагиваются.
|
||||
|
||||
#### Scenario: компонент аутентифицирован после пересоздания
|
||||
|
||||
- **GIVEN** prosody пересоздан через compose
|
||||
- **WHEN** выполняется `docker logs icq-prosody --tail 100`
|
||||
- **THEN** в логах нет ошибок аутентификации, компонент telegram.nixg.ru
|
||||
в списке активных (или нет критических ошибок)
|
||||
|
||||
#### Scenario: мост жив после пересоздания
|
||||
|
||||
- **GIVEN** prosody пересоздан через compose
|
||||
- **WHEN** выполняется `docker logs icq-slidgram --tail 50`
|
||||
- **THEN** нет ошибок подключения/аутентификации; мост в статусе Up
|
||||
@@ -0,0 +1,42 @@
|
||||
# Tasks — icq-fix-prosody-network
|
||||
|
||||
## 1. Снимок состояния до изменений
|
||||
|
||||
- [ ] Зафиксировать `docker ps --format '{{.Names}} {{.Networks}}'` (пустая сеть у prosody)
|
||||
- [ ] Зафиксировать `docker network inspect icq_default` (webchat, slidgram — без prosody)
|
||||
- [ ] Снимок контейнера: `docker inspect icq-prosody > /tmp/icq-prosody-inspect-before.json`
|
||||
|
||||
## 2. Пересоздание prosody через compose
|
||||
|
||||
- [ ] `cd /opt/icq && docker compose up -d --force-recreate prosody`
|
||||
- [ ] Дождаться `Up` (status), зафиксировать `docker ps` для prosody
|
||||
|
||||
## 3. Проверка сети (внутри compose)
|
||||
|
||||
- [ ] `docker ps --format '{{.Names}} {{.Networks}}'` → prolody в icq_default
|
||||
- [ ] `docker network inspect icq_default` → контейнер icq-prosody с IP (172.27.0.x)
|
||||
- [ ] `docker exec icq-prosody hostname -i` → непустой адрес
|
||||
- [ ] `docker exec icq-webchat getent hosts icq-prosody` → резолвится (172.27.0.x)
|
||||
- [ ] `docker exec icq-slidgram getent hosts icq-prosody` → резолвится
|
||||
|
||||
## 4. Проверка приложения и логов
|
||||
|
||||
- [ ] `docker logs icq-prosody --tail 100` — нет новых критических ошибок,
|
||||
компонент telegram.nixg.ru аутентифицирован (или в активных)
|
||||
- [ ] `docker logs icq-webchat --tail 50` — страница отдаётся без ошибок
|
||||
- [ ] `docker logs icq-slidgram --tail 50` — без ошибок аутентификации
|
||||
- [ ] `curl -i` внутренний на prosody:5280 (BOSH/WS) → ответ сервера (не refused)
|
||||
- [ ] `docker compose ps` → все 3 сервиса Up, без Exited/Restarting
|
||||
|
||||
## 5. Проверка снаружи (chat.nixg.ru)
|
||||
|
||||
- [ ] `curl -i https://chat.nixg.ru/` → HTTP 200 (страница Converse)
|
||||
- [ ] WS wss://xmpp.nixg.ru → HTTP 101 Switching Protocols
|
||||
- [ ] (если доступен браузер) chat.nixg.ru открывается, форма входа видна,
|
||||
без бесконечной загрузки
|
||||
|
||||
## 6. Итог и документация
|
||||
|
||||
- [ ] Записать результат в /opt/icq/STATUS.md (секция «Что работает» + журнал инцидента)
|
||||
- [ ] Зафиксировать вывод `docker compose ps` и проверок в коммит-сообщение
|
||||
- [ ] Обновить WALKTHROUGH.md при необходимости (грабли: ручной запуск вне compose → потеря сети)
|
||||
@@ -0,0 +1,45 @@
|
||||
# email-storage-format Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change email-storage-analysis. Update Purpose after archive.
|
||||
|
||||
## 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).
|
||||
Reference in New Issue
Block a user