mirror of
https://gitverse.ru/kpa39l/gotosocial.git
synced 2026-09-29 18:05:09 +00:00
Compare commits
5 Commits
3a0ec485c6
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| e6cd4d5896 | |||
| 275385ccdb | |||
| 568335a643 | |||
| 1cee142631 | |||
| d768c8f2d3 |
@@ -0,0 +1,48 @@
|
||||
# AGENTS.md — Правила для AI-агентов (Hermes)
|
||||
|
||||
## ЖЁСТКОЕ ТРЕБОВАНИЕ: все изменения — через OpenSpec
|
||||
|
||||
**ЛЮБОЕ изменение проекта** (код, docker-compose.yml, config, системные
|
||||
юниты, документация, статусы) **ОБЯЗАНО** проходить через OpenSpec-воркфлоу:
|
||||
|
||||
1. `/openspec-propose <имя-изменения>` — создать change
|
||||
(proposal.md → specs/ delta → design.md → tasks.md).
|
||||
2. `/openspec-apply-change <имя>` — реализовать задачи из tasks.md
|
||||
(с реальной верификацией каждой).
|
||||
3. `/openspec-archive-change <имя>` — влить delta в main specs
|
||||
(`openspec/specs/`), после `openspec validate`.
|
||||
|
||||
**Запрещено** (без исключений):
|
||||
|
||||
- ❌ Править docker-compose.yml / config.yaml / код / юниты напрямую
|
||||
без openspec-change.
|
||||
- ❌ Коммитить изменения без соответствующего openspec-change
|
||||
(коммит = `feat/fix(...): ...; openspec: <change-name>`).
|
||||
- ❌ «Мелкие правки» в обход openspec: статус-файлы, README, доки —
|
||||
тоже изменения, оформляются так же (допускается `skip_specs: true`
|
||||
для чисто документационных правок).
|
||||
|
||||
**Исключения**: только по явной команде пользователя
|
||||
(«сделай в обход openspec» / подтверждение на прямой фикс).
|
||||
|
||||
## Рабочий процесс
|
||||
|
||||
- Прочитать перед действиями: `STATUS.md`, `PRD.md`, `README.md`,
|
||||
`TODO.md`, `openspec/specs/**/spec.md`.
|
||||
- Верификация каждой задачи — реальная команда (curl, docker ps,
|
||||
systemctl status), не предположение.
|
||||
- Секреты: в `.env`, в git не попадают.
|
||||
- Рестарт сервисов — только извне (SSH sudo systemctl restart).
|
||||
- Git: маленькие коммиты; источник истины gitverse.ru.
|
||||
|
||||
## Текущая спецификация
|
||||
|
||||
- `openspec/specs/gotosocial/` — trusted-proxies, webfinger-and-registration,
|
||||
webclient-and-clean-footer, smtp-email.
|
||||
|
||||
## Справочник essentials
|
||||
|
||||
- Контейнер: `gotosocial` (image superseriousbusiness/gotosocial:0.22.1)
|
||||
- Данные: `/opt/gotosocial/data/` (sqlite.db + storage/)
|
||||
- Порт: 8080 внутри, Caddy vps02 → 10.8.0.2:8080
|
||||
- SMTP: smtp.jino.ru:587, `GTS_SMTP_FROM`, `GTS_SMTP_USERNAME` (соц@dedinit.ru)
|
||||
@@ -39,6 +39,21 @@ Internet ──► vps02 87.242.100.206 (Caddy 2, host net)
|
||||
└── openspec/ # OpenSpec-воркфлоу (changes/deploy-gotosocial)
|
||||
```
|
||||
|
||||
## Правила изменений (обязательно)
|
||||
|
||||
**Все изменения проекта** (код, docker-compose.yml, config.yaml, документы,
|
||||
статусы) проводятся **только через OpenSpec-воркфлоу**:
|
||||
|
||||
1. `openspec new change '<имя>'` — proposal → specs (delta) → design → tasks
|
||||
2. выполнение задач из `tasks.md` (каждая — с реальной верификацией)
|
||||
3. `openspec archive '<имя>'` — влить delta в `openspec/specs/`, коммит
|
||||
|
||||
Прямое редактирование файлов или коммиты без openspec-change **запрещены**
|
||||
(SMTP-фикс 13.09 — прецедент, оформлен постфактум как
|
||||
`fix-smtp-from-address`). Исключение — только явная команда владельца.
|
||||
|
||||
Подробно: `AGENTS.md` (корень проекта).
|
||||
|
||||
## Команды
|
||||
|
||||
```bash
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
# GoToSocial — Статус
|
||||
|
||||
Обновлено: 2026-09-07
|
||||
Обновлено: 2026-09-19
|
||||
|
||||
## Текущее состояние
|
||||
|
||||
GoToSocial **запущен и работает** на social.dedinit.ru: контейнер Up, HTTPS 200, админ создан.
|
||||
Split-domain работает: аккаунты `@user@dedinit.ru`, хост social.dedinit.ru, apex-webfinger отдаёт JSON.
|
||||
Ежедневный cron-бэкап (02:00) активен и проверен.
|
||||
Почта: пустой From исправлен (GTS_SMTP_FROM), SPF+DKIM включены (19.09). Мониторинг: дашборд Grafana GoToSocial (20 панелей).
|
||||
|
||||
## Сделано
|
||||
|
||||
@@ -46,12 +47,61 @@ Split-domain работает: аккаунты `@user@dedinit.ru`, хост soc
|
||||
- Кастомный page_footer.tmpl (без 🏳️🌈🏳️⚧️🦥 в подвале), смонтирован volume `./web/template/page_footer.tmpl:ro`
|
||||
- Проверка при обновлении GtS: `./scripts/check-pride.sh` (python3-детект юникода, нормализация; grep-эмодзи ловил ложные срабатывания)
|
||||
|
||||
### Федеративная лента анонимно (2026-09-11)
|
||||
- Пустая федальная лента = GtS 0.22.1 по умолчанию отдаёт 401 на /api/v1/timelines/public без OAuth-токена
|
||||
(`instance-expose-public-timeline: false`). Phanpy открывает ленту до логина → пусто.
|
||||
- ФИКС: `GTS_INSTANCE_EXPOSE_PUBLIC_TIMELINE: "true"` в docker-compose.yml + recreate.
|
||||
Проверено: анонимный GET → 200, статусы есть и снаружи (https://social.dedinit.ru).
|
||||
- **Тренды пустые — НЕ баг конфига**: в GtS 0.22.1 (последний релиз) `/api/v1/trends/{tags,statuses,links}`
|
||||
захардкожены на `EmptyJSONArray` («NOT FULLY IMPLEMENTED») — исходники internal/api/client/trends/*.
|
||||
Никакой env-опцией не включаются. Ждать реализации в новых версиях GtS.
|
||||
|
||||
### Почта: причина найдена и исправлена (2026-09-13)
|
||||
- Симптом: письмо подтверждения приходило В СПАМ и с ПУСТЫМ заголовком `From:`
|
||||
(пользователь: «в поле отправителя ничего не заполнено, поэтому письмо полностью
|
||||
было заблокировано», X-Yandex-Spam: 4).
|
||||
- **Первопричина**: в docker-compose.yml была `GTS_SMTP_FROM_ADDRESS` — НЕСУЩЕСТВУЮЩИЙ ключ.
|
||||
GtS ждёт `smtp-from` → env `GTS_SMTP_FROM` (internal/config + vendored viper:
|
||||
дефисы→подчёркивания, префикс GTS_, UPPER). `GetSMTPFrom()` возвращал "" → заголовок
|
||||
`From: ` пустой при корректном envelope (`Authenticated sender: social@dedinit.ru`).
|
||||
- **ФИКС**: `GTS_SMTP_FROM: "social@dedinit.ru"` в compose + перезапуск контейнера.
|
||||
Проверено: env в контейнере `GTS_SMTP_FROM=social@dedinit.ru`, инстанс жив (HTTPS 200),
|
||||
пользователь kunikov подтверждён вручную (`admin account confirm`), письмо из спама достано.
|
||||
- SMTP Jino при этом был рабочим с самого начала: login OK, RCPT OK, `250 Ok: queued`.
|
||||
RealSender (не Noop): GTS_SMTP_HOST непустой → `email.NewSender()`.
|
||||
- ОСТАЁТСЯ: у dedinit.ru НЕТ SPF и DMARC (DKIM `default` есть). Яндекс кладёт письма в спам
|
||||
без SPF/DMARC независимо от From. Нужно: SPF TXT `v=spf1 a mx include:jino.ru ~all`
|
||||
(или из панели Jino) + DMARC `_dmarc.dedinit.ru`.
|
||||
|
||||
### Системное: systemd1 D-Bus завис → dockerd переведён на cgroupfs (2026-09-13)
|
||||
- При перезапуске gotosocial `docker compose up` упал: `Failed to activate service
|
||||
'org.freedesktop.systemd1': timed out` — systemd1 не отвечал по D-Bus (25s таймаут),
|
||||
системные вызовы systemctl/dbus-send тоже зависали. Причина не выяснена
|
||||
(фоновый шум mount.davfs «open files exceed max cache size by 3400 MiB» в журнале).
|
||||
- ВАЖНО: cgroup-драйвер docker был `systemd` → каждый старт контейнера шёл через systemd1.
|
||||
- **ФИКС**: `/etc/docker/daemon.json` → `"exec-opts": ["native.cgroupdriver=cgroupfs"]`,
|
||||
dockerd перезапущен вручную (nohup dockerd --containerd=... ). Все контейнеры живы,
|
||||
метрики/инстанс работают.
|
||||
- **ДОЛГ**: после ПЕРЕЗАГРУЗКИ сервера dockerd поднимется через systemd; если systemd1 снова
|
||||
зависнет — контейнеры не стартуют. Проверить после рестарта сервера.
|
||||
- Побочный эффект: с хоста 127.0.0.1:8082 curl висит (docker-proxy НЕ отвечает), но внешний
|
||||
доступ social.dedinit.ru (Caddy vps02 → 10.8.0.2:8082) работает — инстанс полностью жив.
|
||||
|
||||
## В работе / Следующие шаги
|
||||
|
||||
- [x] Регистрация открыта (10/день) + apex-webfinger динамический (change fix-apex-webfinger-and-registration, архив)
|
||||
- [x] Веб-клиент Phanpy + чистый подвал (change add-webclient-and-clean-footer)
|
||||
- [ ] Мониторинг: пробросить :9464 (метрики уже слушают), job в prometheus.yml, дашборд Grafana
|
||||
(инструкция по метрикам GtS получена от пользователя 2026-09-06)
|
||||
- [x] **Отладка почты** (13.09): причина найдена — `GTS_SMTP_FROM_ADDRESS` вместо `GTS_SMTP_FROM` → пустой From; исправлено, kunikov подтверждён
|
||||
- [x] **SPF/DMARC для dedinit.ru** (Jino, 19.09): DKIM включён
|
||||
(dkim._domainkey.dedinit.ru, IN TXT, v=DKIM1; t=s; p=…), SPF включён
|
||||
(dedinit.ru, IN TXT, v=spf1 redirect=_spf.jino.ru). DMARC — см. «Открытые
|
||||
вопросы».
|
||||
- [x] **Мониторинг GtS** (19.09): job `gotosocial` в prometheus.yml —
|
||||
127.0.0.1:9464/metrics; дашборд Grafana `GoToSocial` (папка gotosocial,
|
||||
uid gotosocial-main, 20 панелей: доступность/instance/workers/HTTP/SQL/
|
||||
процесс). Заодно исправлено пересечение провайдеров dashboards.yml
|
||||
(garage-dashboards смотрел на весь каталог → блокировал запись всех
|
||||
дашбордов). Openspec: add-gotosocial-dashboard (archive).
|
||||
- [ ] Логи в json-формате при желании (log-format: json) — по умолчанию logfmt
|
||||
|
||||
## Процедура при обновлении версии GtS (важно!)
|
||||
@@ -92,4 +142,5 @@ bash backup.sh && ls -lh backups/
|
||||
## Открытые вопросы
|
||||
|
||||
- Пароль админа: создан с паролем из сессии (если менялся — обновить в заметках)
|
||||
- DMARC для dedinit.ru — SPF и DKIM включены (19.09), DMARC не подтверждён в панели Jino (рекомендовано `v=DMARC1; p=none; rua=mailto:admin@dedinit.ru`)
|
||||
- ZFS-бэкапы/другие ротации не требуются (хватает local 7д + ЯД 30д)
|
||||
@@ -4,22 +4,24 @@
|
||||
|
||||
## Открытые
|
||||
|
||||
| 2026-09-06 | Развернуть сервис на bigbox: `docker compose up -d` | 🔵 открыта | |
|
||||
| 2026-09-06 | Создать админа estorozhenko (gotosocial admin account create --confirmation + promote) | 🔵 открыта | |
|
||||
| 2026-09-06 | Caddy на vps02: блок social.dedinit.ru → 10.8.0.2:8080 + reload | 🔵 открыта | |
|
||||
| 2026-09-06 | Split-domain apex: .well-known редиректы (webfinger/nodeinfo/host-meta) на dedinit.ru (Jino) | 🔵 открыта | |
|
||||
| 2026-09-06 | Проверить HTTPS (сертификат LE), webfinger, SMTP, /metrics | 🔵 открыта | |
|
||||
| 2026-09-06 | Настроить cron бэкапа (backup.sh готов) | 🔵 открыта | |
|
||||
| 2026-09-19 | Логи в json-формате (log-format: json) — по умолчанию logfmt | 🔵 открыта | |
|
||||
| 2026-09-19 | DMARC для dedinit.ru — SPF и DKIM включены (19.09), DMARC не подтверждён в панели Jino | 🔵 открыта | |
|
||||
|
||||
## Post-MVP (отложено)
|
||||
|
||||
| 2026-09-06 | Дашборд Grafana для GoToSocial (метрики) | 🔵 отложено | |
|
||||
| 2026-09-06 | Мониторинг бэкапов (метрика в Prometheus, дашборд «бэкап создан/лежит локально/ЯД/удалён по ротации») | 🔵 отложено | |
|
||||
| 2026-09-06 | Импорт из Telegram | 🔵 отложено | |
|
||||
| 2026-09-08 | Релей федерации (Activity-Relay от yukimochi, Go): https://github.com/yukimochi/Activity-Relay — relay.toot.io | 🔵 отложено | |
|
||||
| 2026-09-08 | Форк Phanpy: показывать кнопки Like/Boost прямо в ленте (сейчас спрятаны в «три точки»; в status.jsx панель рендерится только при showActionsBar, boost-кнопка закомментирована) — очередь 3, долгий ящик | 🔵 отложено | |
|
||||
|
||||
## Закрытые
|
||||
|
||||
| 2026-09-06 | Развернуть сервис на bigbox: `docker compose up -d` | ✅ закрыта | сессия 2026-09-06 |
|
||||
| 2026-09-06 | Создать админа estorozhenko (gotosocial admin account create --confirmation + promote) | ✅ закрыта | сессия 2026-09-06 |
|
||||
| 2026-09-06 | Caddy на vps02: блок social.dedinit.ru → 10.8.0.2:8080 + reload | ✅ закрыта | сессия 2026-09-06 |
|
||||
| 2026-09-06 | Split-domain apex: .well-known редиректы (webfinger/nodeinfo/host-meta) на dedinit.ru (Jino) | ✅ закрыта | сессия 2026-09-06 |
|
||||
| 2026-09-06 | Проверить HTTPS (сертификат LE), webfinger, SMTP, /metrics | ✅ закрыта | сессия 2026-09-06 |
|
||||
| 2026-09-06 | Настроить cron бэкапа (backup.sh готов) | ✅ закрыта | сессия 2026-09-06 |
|
||||
| 2026-09-06 | Исследование развёртывания GoToSocial v0.22.1 (доки, split-domain, Docker, метрики) | ✅ закрыта | сессия 2026-09-06 |
|
||||
| 2026-09-06 | Каталог /opt/gotosocial + OpenSpec init + change deploy-gotosocial (proposal/spec/design/tasks) | ✅ закрыта | сессия 2026-09-06 |
|
||||
| 2026-09-06 | openspec validate deploy-gotosocial → valid | ✅ закрыта | сессия 2026-09-06 |
|
||||
@@ -31,4 +33,12 @@
|
||||
| 2026-09-06 | git init + commit d385d8b | ✅ закрыта | сессия 2026-09-06 |
|
||||
| 2026-09-06 | gitverse репо kpa39l/gotosocial (API, Bearer+Accept object+json), push main | ✅ закрыта | сессия 2026-09-06 |
|
||||
| 2026-09-06 | gitea.nixg.ru pull-mirror estorozhenko/gotosocial (8ч), первая синхронизация | ✅ закрыта | сессия 2026-09-06 |
|
||||
| 2026-09-06 | Убрать токен из git remote URL (оставить https://kpa39l@gitverse.ru/...) | ✅ закрыта | сессия 2026-09-06 |
|
||||
| 2026-09-06 | Убрать токен из git remote URL (оставить https://kpa39l@gitverse.ru/...) | ✅ закрыта | сессия 2026-09-06 |
|
||||
| 2026-09-07 | Веб-клиент Phanpy + чистый подвал (page_footer.tmpl без 🏳️🌈🏳️⚧️, check-pride.sh) | ✅ закрыта | сессия 2026-09-07 |
|
||||
| 2026-09-11 | Пустая федальная лента анонимно: GTS_INSTANCE_EXPOSE_PUBLIC_TIMELINE=true | ✅ закрыта | сессия 2026-09-11 |
|
||||
| 2026-09-13 | Отладка почты: GTS_SMTP_FROM_ADDRESS → GTS_SMTP_FROM (пустой From); docker-compose.yml + FIX | ✅ закрыта | сессия 2026-09-13 |
|
||||
| 2026-09-13 | systemd1 D-Bus завис → dockerd на cgroupfs (native.cgroupdriver=cgroupfs в daemon.json) | ✅ закрыта (проверить после ребута сервера!) | сессия 2026-09-13 |
|
||||
| 2026-09-13 | OpenSpec-change fix-smtp-from-address (posthoc) → spec smtp-email в archive | ✅ закрыта | сессия 2026-09-13-14 |
|
||||
| 2026-09-19 | Жёсткое требование: все изменения проекта — через OpenSpec (AGENTS.md, README, openspec/config.yaml, spec project-governance) | ✅ закрыта | сессия 2026-09-19 |
|
||||
| 2026-09-19 | SPF+DKIM dedinit.ru в панели Jino (SPF: v=spf1 redirect=_spf.jino.ru; DKIM: dkim._domainkey IN TXT) | ✅ закрыта | сессия 2026-09-19 |
|
||||
| 2026-09-19 | Мониторинг GtS: дашборд Grafana GoToSocial (uid gotosocial-main, 20 панелей) — /opt/monitoring, openspec add-gotosocial-dashboard | ✅ закрыта | сессия 2026-09-19 |
|
||||
+60
-1
@@ -108,4 +108,63 @@ Caddy vps02: блок `social.dedinit.ru { reverse_proxy 10.8.0.2:8080 }`, `dock
|
||||
- Как GtS читает SMTP-пароль: config.yaml `smtp-password: ""` + .env `GTS_SMTP_PASSWORD` — проверить при первом запуске, что письма уходят
|
||||
- Пароль админа estorozhenko — нужен от пользователя
|
||||
- Доступ к vps02 для правки Caddyfile — нужен (SSH estorozhenko@87.242.100.206 + cloudruVPS ключ)
|
||||
- .well-known редиректы на apex (Jino) — подготовить правила
|
||||
- .well-known редиректы на apex (Jino) — подготовить правила
|
||||
|
||||
## 2026-09-13 — Почта: пустой From → спам (причина и фикс)
|
||||
|
||||
### Симптом
|
||||
- Письма GoToSocial (подтверждение регистрации и т.п.) уходили на внешние ящики (Яндекс) в СПАМ.
|
||||
- Заголовки: `From: <>` (пустой) — письмо без отправителя.
|
||||
- X-Yandex-Spam: 4 (pessimistic).
|
||||
|
||||
### Диагностика
|
||||
1. SMTP Jino напрямую (python smtplib): логин social@dedinit.ru OK, RCPT kpa39l@ya.ru OK, DATA → `250 Ok: queued`. SMTP-стек рабочий.
|
||||
2. DNS dedinit.ru: SPF и DMARC ОТСУТСТВОВАЛИ; DKIM `default._domainkey` был.
|
||||
3. Исходники GtS (/tmp/gts-src, v0.22.1), state.go:100-101: флаг `--smtp-from` → env `GTS_SMTP_FROM`.
|
||||
4. В docker-compose.yml стоял **неверный** env: `GTS_SMTP_FROM_ADDRESS` (такого ключа нет → From пустой).
|
||||
|
||||
### Фикс
|
||||
```bash
|
||||
# docker-compose.yml: GTS_SMTP_FROM_ADDRESS: "..." → GTS_SMTP_FROM: "social@dedinit.ru"
|
||||
cd /opt/gotosocial && docker compose up -d --force-recreate gotosocial
|
||||
```
|
||||
|
||||
### Питфол — systemd1 D-Bus завис
|
||||
- `docker compose up` завис: systemd1 D-Bus таймаут 25s, контейнер остался `Created`.
|
||||
- Обход: `/etc/docker/daemon.json` → `"native.cgroupdriver": "cgroupfs"`, `systemctl restart docker` (вручную, минуя systemd1).
|
||||
- **Риск:** после перезагрузки bigbox dockerd может не подняться сам (systemd1 фризит). Проверить при следующем ребуте. (Другой вариант — перезапуск systemd как PID 1; не делали.)
|
||||
|
||||
### Проверка
|
||||
- `docker exec gotosocial /gotosocial/gotosocial admin account list` — kunikov был unconfirmed (unconfirmed_email=kpa39l@ya.ru), подтверждён вручную `admin account confirm kunikov`.
|
||||
- Внешний https://social.dedinit.ru → 200; письма теперь от social@dedinit.ru (непустой From).
|
||||
|
||||
### Openspec (posthoc)
|
||||
- change `fix-smtp-from-address` → spec `gotosocial/smtp-email` (3 MUST: корректные env-ключи SMTP, непустой From, SPF/DMARC), archive.
|
||||
- Коммит `1cee142`: docker-compose.yml + STATUS.md + openspec.
|
||||
|
||||
## 2026-09-19 — Управление проектом + SPF/DKIM + мониторинг
|
||||
|
||||
### Жёсткое правило openspec (AGENTS.md)
|
||||
- По требованию пользователя в проект добавлено правило: **все изменения — через OpenSpec** (propose → apply-change → archive); исключение — явная команда владельца с `bypass-openspec:` в коммите.
|
||||
- Носители: AGENTS.md (для агентов), openspec/config.yaml (context — инжектится во все артефакты), README.md (для людей), spec `gotosocial/project-governance` (3 требования со Scenario).
|
||||
- change `enforce-openspec-workflow` → archive. Коммит `568335a`.
|
||||
|
||||
### SPF/DKIM (Jino, панель домена)
|
||||
- SPF: `v=spf1 redirect=_spf.jino.ru` (хост dedinit.ru, IN TXT) — включено пользователем 19.09.
|
||||
- DKIM: `v=DKIM1; t=s; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A…` (хост dkim._domainkey.dedinit.ru, IN TXT) — включено.
|
||||
- DMARC: **не подтверждён** (ранее рекомендовано `v=DMARC1; p=none; rua=mailto:admin@dedinit.ru`). Открытая задача.
|
||||
|
||||
### Мониторинг :9464 (дашборд Grafana)
|
||||
- Job `gotosocial` в /opt/monitoring/prometheus.yml уже был (127.0.0.1:9464/metrics, relabel instance=bigbox:9464); VictoriaMetrics (127.0.0.1:9090) тянет — проверено `/api/v1/series?match[]=gotosocial_instance_total_users`.
|
||||
- Создан дашборд `/opt/monitoring/grafana/dashboards/gotosocial/gotosocial.json` (генератор `scripts/gen_gotosocial_dash.py`, 20 панелей: Доступность/Инстанс/Воркеры/HTTP/SQL/Процесс; uid gotosocial-main).
|
||||
- dashboards.yml: добавлен провайдер `gotosocial-dashboards` (folder gotosocial). **Заодно починен дефект:** провайдер `garage-dashboards` смотрел на ВЕСЬ `/var/lib/grafana/dashboards`, дублируя nodes/vinogorod/vesti → Grafana блокировала запись всех новых дашбордов («the same UID is used more than once» + «no database write permissions because of duplicates»). Сужен до `/var/lib/grafana/dashboards/garage-cluster.json`; `docker compose restart grafana`.
|
||||
- Проверка: `gotosocial-main` в grafana.db, папка gotosocial (id 23), dashboard_provisioning содержит запись.
|
||||
- Openspec: change `add-gotosocial-dashboard` → spec `gotosocial-monitoring` (в /opt/monitoring), archive; коммит `ee92496` (monitoring); STATUS.md gotosocial → `275385c`.
|
||||
|
||||
### Git (эта сессия)
|
||||
- /opt/gotosocial: `568335a` (governance), `275385c` (status) — запушены на gitverse.
|
||||
- /opt/monitoring: `ee92496` — запушен на gitverse + mirror-sync на gitea (HTTP 200, POST /api/v1/repos/estorozhenko/monitoring/mirror-sync, токен из git-tokens.env).
|
||||
- mirror-sync gitea: http://gitea.nixg.ru → 308 на https:// — использовать https или python urllib с redirect.
|
||||
|
||||
### Находка (не исправлена)
|
||||
- config.py:45 — дефект `==` вместо `!=` (исходники GtS, /tmp/gts-src) — зафиксировать, не фикс.
|
||||
+9
-2
@@ -30,6 +30,8 @@ services:
|
||||
GTS_INSTANCE_TITLE: "dedinit()"
|
||||
GTS_INSTANCE_DESCRIPTION: "Нода для обычных людей"
|
||||
GTS_INSTANCE_CONTACT_EMAIL: "kpa39l@yandex.ru"
|
||||
# Перезапуск: федальная лента анонимно (иначе /api/v1/timelines/public → 401)
|
||||
GTS_INSTANCE_EXPOSE_PUBLIC_TIMELINE: "true"
|
||||
# Регистрация открыта: 10 новых аккаунтов в сутки (лимит очереди одобрения — дефолт 20)
|
||||
GTS_ACCOUNTS_REGISTRATION_OPEN: "true"
|
||||
GTS_ACCOUNTS_REGISTRATION_DAILY_LIMIT: "10"
|
||||
@@ -37,7 +39,7 @@ services:
|
||||
GTS_SMTP_HOST: "smtp.jino.ru"
|
||||
GTS_SMTP_PORT: "587"
|
||||
GTS_SMTP_USERNAME: "social@dedinit.ru"
|
||||
GTS_SMTP_FROM_ADDRESS: "social@dedinit.ru"
|
||||
GTS_SMTP_FROM: "social@dedinit.ru"
|
||||
# Метрики Prometheus (OTEL)
|
||||
GTS_METRICS_ENABLED: "true"
|
||||
GTS_METRICS_AUTH_ENABLED: "false"
|
||||
@@ -79,7 +81,12 @@ services:
|
||||
- "8383:8080"
|
||||
|
||||
networks:
|
||||
gotosocial:
|
||||
default:
|
||||
driver: bridge
|
||||
driver_opts:
|
||||
# MTU 1500 не проходит через WG-туннель (wg0 mtu 1420) → таймауты исходящих
|
||||
# соединений (фрагментация теряется, DF-бит). 1380 безопасно ниже 1420.
|
||||
com.docker.network.driver.mtu: "1380"
|
||||
ipam:
|
||||
config:
|
||||
# Выделенная подсеть (172.29.0.0/16 свободна на bigbox)
|
||||
|
||||
@@ -12,6 +12,7 @@ context: |
|
||||
Мониторинг: Prometheus на bigbox (127.0.0.1:9090, host net), Grafana :3001 (grafana.nixg.ru), Loki :3100 + promtail; метрики GtS: metrics-enabled + OTEL prometheus; логи: log-format json → promtail job.
|
||||
Git: источник истины gitverse.ru (kpa39l), gitea.nixg.ru — pull-mirror (8h). Коммиты — маленькие, по изменениям.
|
||||
Версии: последний стабильный релиз GtS, фиксированный тег в compose, обновление вручную.
|
||||
СЛУЖЕБНОЕ ПРАВИЛО: ЛЮБОЕ изменение проекта (код, конфиги, доки, статусы) проводится ТОЛЬКО через OpenSpec-воркфлоу (openspec new change → apply tasks → archive): прямое редактирование файлов или коммиты без openspec-change ЗАПРЕЩЕНЫ; исключение — только явная команда пользователя.
|
||||
|
||||
rules:
|
||||
proposal:
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# gotosocial/project-governance Specification
|
||||
|
||||
## Purpose
|
||||
Определить обязательный процесс управления изменениями проекта: любое
|
||||
изменение (код, конфигурация, документация, статусы) проводится только через
|
||||
OpenSpec-воркфлоу. Введено по явному распоряжению владельца 2026-09-13.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: OpenSpec-воркфлоу обязателен для всех изменений
|
||||
|
||||
- **MUST**: Каждое изменение проекта оформляется как openspec-change
|
||||
(`openspec new change '<name>'`) с артефактами proposal → specs (delta) →
|
||||
design → tasks, в соответствии со schema `spec-driven`.
|
||||
- **MUST**: Реализация выполняется по задачам из `tasks.md`; каждая задача —
|
||||
с реальной верификацией (команда/тест/наблюдаемое поведение), подтверждение
|
||||
«сделано» без проверки не принимается.
|
||||
- **MUST**: После реализации change архивируется
|
||||
(`openspec archive '<name>' --yes`), delta вливается в
|
||||
`openspec/specs/<capability>/`; итог валиден (`openspec validate`).
|
||||
- **MUST NOT**: Прямое редактирование файлов проекта (docker-compose.yml,
|
||||
config.yaml, код, системные юниты, README/STATUS/TODO, openspec/specs)
|
||||
без openspec-change.
|
||||
|
||||
#### Scenario: Прямая правка запрещена
|
||||
|
||||
- **GIVEN** владелец дал задачу на изменение (например, «добавь правило в файлы»)
|
||||
- **WHEN** агент хочет править файл напрямую, без openspec-change
|
||||
- **THEN** действие отклоняется: сначала создаётся openspec-change,
|
||||
задачи применяются, change архивируется
|
||||
|
||||
#### Scenario: Изменение через воркфлоу допустимо
|
||||
|
||||
- **GIVEN** изменение проекта (код или конфиг)
|
||||
- **WHEN** создан openspec-change, задачи выполнены и верифицированы,
|
||||
change заархивирован, `openspec validate` проходит
|
||||
- **THEN** изменение считается легитимным и коммитится
|
||||
(`feat/fix(...): ...; openspec: <change-name>`)
|
||||
|
||||
### Requirement: Источники правила для агентов и людей
|
||||
|
||||
- **MUST**: Правило зафиксировано в `AGENTS.md` (корень проекта) — файл
|
||||
авто-подхватывается агентами (Hermes/Claude) при работе в проекте.
|
||||
- **MUST**: Правило включено в `openspec/config.yaml` (`context`) — оно
|
||||
инжектится в каждый артефакт openspec.
|
||||
- **SHOULD**: Правило продублировано в `README.md` (видно человеку при
|
||||
первом знакомстве с проектом).
|
||||
|
||||
#### Scenario: Агент видит правило
|
||||
|
||||
- **GIVEN** агент работает в /opt/gotosocial
|
||||
- **WHEN** он открывает сессию
|
||||
- **THEN** в `AGENTS.md` он находит «ЖЁСТКОЕ ТРЕБОВАНИЕ: все изменения —
|
||||
через OpenSpec» с запретами и исключениями
|
||||
|
||||
### Requirement: Исключение только по команде владельца
|
||||
|
||||
- **MAY**: Прямое изменение допускается только после явной команды
|
||||
владельца («сделай в обход openspec», подтверждение на прямой фикс).
|
||||
- **MUST**: Исключение фиксируется в коммит-сообщении (например,
|
||||
`bypass-openspec: <причина>`), чтобы оставаться аудируемым.
|
||||
|
||||
#### Scenario: Явный обход
|
||||
|
||||
- **GIVEN** владелец сказал «сделай напрямую, без openspec»
|
||||
- **WHEN** агент вносит изменение
|
||||
- **THEN** изменение допустимо, но помечается в коммите
|
||||
(`bypass-openspec: <причина>`)
|
||||
@@ -0,0 +1,74 @@
|
||||
# gotosocial/smtp-email Specification
|
||||
|
||||
## Purpose
|
||||
Обеспечить доставляемость исходящих писем GoToSocial (подтверждение email,
|
||||
системные уведомления) через SMTP Jino, гарантируя корректный, непустой
|
||||
заголовок `From` и валидную аутентификацию. Исправление применено 2026-09-13
|
||||
(пустой From из-за неверной env-переменной `GTS_SMTP_FROM_ADDRESS`).
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: SMTP-конфигурация через корректные env-ключи GtS
|
||||
|
||||
- **MUST**: Исходящая почта настраивается через env-переменные, которые
|
||||
GtS 0.22.x реально читает (префикс `GTS_`, ключи конфига `smtp-*`):
|
||||
`GTS_SMTP_HOST`, `GTS_SMTP_PORT`, `GTS_SMTP_USERNAME`,
|
||||
`GTS_SMTP_PASSWORD`, `GTS_SMTP_FROM`.
|
||||
- **MUST NOT**: НЕ используется `GTS_SMTP_FROM_ADDRESS` — такого ключа GtS
|
||||
не знает, он молча игнорируется, и заголовок `From` в письмах становится
|
||||
пустым.
|
||||
- **MUST**: `GTS_SMTP_FROM` и `GTS_SMTP_USERNAME` совпадают
|
||||
(`social@dedinit.ru`) — envelope-отправитель и заголовок From согласованы.
|
||||
|
||||
#### Scenario: From заполнен после фикса
|
||||
|
||||
- **GIVEN** docker-compose.yml содержит `GTS_SMTP_FROM: "social@dedinit.ru"`
|
||||
и контейнер пересоздан
|
||||
- **WHEN** выполнить
|
||||
`docker inspect -f '{{.Config.Env}}' gotosocial | tr ' ' '\n' | grep GTS_SMTP_FROM`
|
||||
- **THEN** вывод содержит `GTS_SMTP_FROM=social@dedinit.ru`
|
||||
|
||||
#### Scenario: Неверный ключ отсутствует
|
||||
|
||||
- **GIVEN** конфигурация в docker-compose.yml
|
||||
- **WHEN** выполнить `grep -c GTS_SMTP_FROM_ADDRESS docker-compose.yml`
|
||||
- **THEN** результат равен `0` (несуществующий ключ больше не используется)
|
||||
|
||||
### Requirement: Регистрационные письма приходят с заполненным From
|
||||
|
||||
- **MUST**: Письмо подтверждения email (шаблон `email_confirm`) отправляется
|
||||
с непустым заголовком `From`, равным `social@dedinit.ru` (значение
|
||||
`GTS_SMTP_FROM` → `GetSMTPFrom()` не пуст).
|
||||
- **SHOULD**: Периодически проверять доставляемость вручную (тестовое письмо
|
||||
через SMTP Jino).
|
||||
|
||||
#### Scenario: Письмо подтверждения после регистрации
|
||||
|
||||
- **GIVEN** настроен SMTP (host/port/username/password/from)
|
||||
- **WHEN** пользователь регистрируется на инстансе
|
||||
(`https://social.dedinit.ru/signup`)
|
||||
- **THEN** в письме подтверждения поле `From` непустое и равно
|
||||
`social@dedinit.ru`, а `confirmation_sent_at`/`last_emailed_at` у
|
||||
пользователя в БД проставлены
|
||||
|
||||
#### Scenario: SMTP-доступность Jino
|
||||
|
||||
- **GIVEN** SMTP smtp.jino.ru:587
|
||||
- **WHEN** проверить ESMTP-баннер и аутентификацию `social@dedinit.ru`
|
||||
- **THEN** баннер `220 smtp-out*.jino.ru ESMTP Postfix`, логин проходит,
|
||||
RCPT TO принимается, DATA → `250 Ok: queued`
|
||||
|
||||
### Requirement: Осведомлённость о репутации домена (SPF/DMARC)
|
||||
|
||||
- **SHOULD**: Для полной доставляемости на внешние ящики (Яндекс и др.) у
|
||||
домена dedinit.ru настроены SPF (`include:jino.ru`) и DMARC; без них
|
||||
письма могут попадать в спам даже при корректном From.
|
||||
- **SHOULD**: Задача настройки SPF/DMARC отслеживается отдельным трекером
|
||||
и не блокирует данный фикс.
|
||||
|
||||
#### Scenario: Проверка наличия SPF
|
||||
|
||||
- **GIVEN** домен dedinit.ru
|
||||
- **WHEN** выполнить `dig +short TXT dedinit.ru`
|
||||
- **THEN** среди записей есть строка, начинающаяся с `v=spf1` (включает
|
||||
jino.ru), либо задача открыта в STATUS.md
|
||||
Reference in New Issue
Block a user