docs: plan specification retirement via D9 migration map
After the documentation pass, specification.md moves to archive once its content lives in product, architecture, development, and security docs. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+99
-50
@@ -1,11 +1,22 @@
|
||||
# План документации SelfPost
|
||||
|
||||
**Зачем этот файл.** Документация — часть поставки (ТЗ раздел 11, пп. 5, 7, 9),
|
||||
а не сопроводительный текст. Перед тегом релиза она обязана описывать **то, что
|
||||
делает код**, а не то, что задумывалось: расхождение здесь — такой же дефект,
|
||||
как несоответствие ТЗ, только обнаруживает его пользователь на своём проде.
|
||||
План описывает, из чего состоит пакет, как он сверяется с кодом, что уже
|
||||
разошлось (первый проход выполнен, результаты ниже) и что с этим делать.
|
||||
**Зачем этот файл.** Документация — часть поставки (deliverables v1.0, пп. 5, 7, 9
|
||||
в [specification.md](specification.md)), а не сопроводительный текст. Перед тегом
|
||||
релиза она обязана описывать **то, что делает код**, а не то, что задумывалось:
|
||||
расхождение здесь — такой же дефект, как несоответствие требованиям, только
|
||||
обнаруживает его пользователь на своём проде. План описывает, из чего состоит
|
||||
пакет, как он сверяется с кодом, что уже разошлось (первый проход выполнен,
|
||||
результаты ниже) и что с этим делать.
|
||||
|
||||
**Цель после выполнения плана:** [specification.md](specification.md) (ТЗ v1.0)
|
||||
**выводится из обращения** — не потому что требования исчезли, а потому что v1.0
|
||||
реализован и каждый блок ТЗ получает постоянный дом: пользовательское — в
|
||||
README, устройство — в `architecture.md`, продуктовые границы — в
|
||||
`product.md`, обязательная безопасность — в `security.md`, процесс разработки —
|
||||
в `development.md`. Живой `specification.md` после этого держит два риска:
|
||||
дублирование с кодом и ложное ощущение «источника истины», который уже не
|
||||
сверяют. Задача **D9** — миграция остатков и снятие файла; до её закрытия
|
||||
ссылки на ТЗ в этом файле — исторические.
|
||||
|
||||
**Место в общем плане:** документационный проход идёт вместе с **D.5**
|
||||
([implementation-plan.md](implementation-plan.md)) — до тега следующего релиза,
|
||||
@@ -32,38 +43,49 @@
|
||||
|
||||
### Рабочие документы проекта (не поставка, но обязаны быть верны)
|
||||
|
||||
[specification.md](specification.md) — ТЗ v1.0, источник истины по требованиям.
|
||||
[specification.md](specification.md) — ТЗ v1.0; **на вывод после D9** (см. карту
|
||||
миграции ниже). До закрытия D9 — ещё используется как историческая ссылка в
|
||||
находках раздела 3.
|
||||
[implementation-plan.md](implementation-plan.md) — открытые вопросы для v1.0/v1.x.
|
||||
[roadmap.md](roadmap.md) — линия 2.x.x.
|
||||
[progress.md](progress.md) — живой трекер, читается первым после `/clear`.
|
||||
[security.md](security.md) — принятые риски. Этот файл — план по документации.
|
||||
[security.md](security.md) — обязательные требования безопасности + принятые
|
||||
риски. Этот файл — план по документации.
|
||||
|
||||
**Новое: `docs/architecture.md` и `docs/development.md` — нужны, решение
|
||||
принято.** ТЗ их не требует (ТЗ 11 не относит их к обязательной поставке), но
|
||||
без них понимание устройства и повторная сборка проекта держатся только на
|
||||
памяти и контексте текущей сессии — то есть не переживают её потерю ни для
|
||||
будущего контрибьютора, ни для будущего прохода без доступа к истории чата.
|
||||
Обе — рабочие документы проекта (не часть поставки пользователю, не
|
||||
упоминаются в README как обязательные), задача заведена в разделе 4 (**D8**).
|
||||
**Новые `product.md`, `architecture.md`, `development.md` — решение принято.**
|
||||
В обязательную поставку пользователю (README) они не входят, но без них
|
||||
понимание проекта держится на памяти сессии. Их содержимое **заменяет** живой
|
||||
`specification.md` для всех будущих проходов — задачи **D8** и **D9**.
|
||||
|
||||
- `docs/architecture.md` — компоненты контейнера (`supervisord`,
|
||||
`postfix`, `opendkim`, `panel`, milter-цепочка) и как они связаны; путь
|
||||
письма через тракт (SMTP submission → milter'ы → OpenDKIM → доставка);
|
||||
что читает/пишет `/data` и в каком формате; где проходит граница
|
||||
привилегий (root vs непривилегированный uid панели) и почему —
|
||||
источник истины: код (`build/supervisord.conf`, `internal/`), а не
|
||||
ТЗ, план сверки — тот же метод из раздела 2.
|
||||
- `docs/development.md` — как собрать и прогнать тесты локально (Go
|
||||
локально, без Docker — см. память проекта), когда нужен полный
|
||||
контейнерный цикл на dev-сервере (сборка образа, milter/почтовые
|
||||
изменения) и почему локальной сборки недостаточно, порядок ручной
|
||||
проверки на `selfpost.mixfed.ru` перед мёржем. Заменяет часть, что
|
||||
раньше держалась только в памяти проекта и `progress.md` — там
|
||||
остаётся текущее состояние и следующий шаг, а не воспроизводимая
|
||||
процедура.
|
||||
- `docs/product.md` — из ТЗ §1–3 и §4.1: зачем SelfPost, инфраструктурные
|
||||
предпосылки, out of scope, мультидоменная модель «домен ↔ приложения ↔
|
||||
режим From». Границы продукта, меняющиеся только явным решением.
|
||||
- `docs/architecture.md` — as-built по коду: `supervisord`, `postfix`,
|
||||
`opendkim`, panel (HTTP + journal-milter + log-tailer); порядок старта;
|
||||
milter-цепочка; Postfix/SASL/TLS; журнал отправки и L1/L2 rate-limit;
|
||||
бэкап/restore; персистентность `/data`. Источник истины — код, не ТЗ.
|
||||
- `docs/development.md` — Go локально, `go test`/`go vet`, `make e2e`, когда
|
||||
нужен полный контейнер на dev-сервере, ручная проверка на
|
||||
`selfpost.mixfed.ru`, протокол коммитов/CHANGELOG, правила для агента
|
||||
(бывшее ТЗ §12). В `progress.md` — текущее состояние, не процедура.
|
||||
|
||||
### Карта миграции из `specification.md`
|
||||
|
||||
| Блок ТЗ | Новый дом | Задача |
|
||||
|---|---|---|
|
||||
| §1–3, §4.1 | `product.md` | D9 |
|
||||
| §4, §5–7 (техника), §9 | `architecture.md` | D8 |
|
||||
| §7.6 | `security.md` («Обязательные требования») | D9 |
|
||||
| §8 | README (таблица env) | D2 |
|
||||
| §9 (путь `tar` для пользователя) | README | D3 |
|
||||
| §10–11 | README + таблица «Поставка» выше | D1–D4 |
|
||||
| §12 | `development.md` | D8 |
|
||||
|
||||
После D9: `specification.md` → `docs/archive/specification-v1.0.md` (снимок,
|
||||
не правится); в `docs/` живых ссылок на него нет.
|
||||
|
||||
**Границы (без изменений):** отдельные `CONTRIBUTING.md`, man-страницы и сайт
|
||||
документации ТЗ по-прежнему не требует и в объём v1.x не входят.
|
||||
документации в объём v1.x не входят.
|
||||
|
||||
---
|
||||
|
||||
@@ -82,11 +104,16 @@
|
||||
| Сессии, вход, смена пароля | [internal/store/sessions.go](../internal/store/sessions.go), [internal/web/session.go](../internal/web/session.go), [internal/web/handlers_account.go](../internal/web/handlers_account.go) |
|
||||
| Ротация лога, периодический reload, интервалы | [build/logrotate-mail.conf](../build/logrotate-mail.conf), [build/logrotate-loop.sh](../build/logrotate-loop.sh), [build/postfix-cert-reload.sh](../build/postfix-cert-reload.sh) |
|
||||
| Деплой: тег образа, порты, монтирования, capabilities | [deploy/docker-compose.yml](../deploy/docker-compose.yml), [build/Dockerfile](../build/Dockerfile) |
|
||||
| Требования, а не реализация (что вообще должно быть описано) | [specification.md](specification.md) разделы 9, 10, 11 |
|
||||
| Обязательное содержание README (чеклист поставки) | таблица «Поставка» в §1 этого файла (бывшее ТЗ §10–11) |
|
||||
| Границы продукта, out of scope | [product.md](product.md) *(после D9)* |
|
||||
| As-built устройство (не пользовательский текст) | [architecture.md](architecture.md) *(после D8)* |
|
||||
| Обязательные требования безопасности | [security.md](security.md) *(после D9)* |
|
||||
|
||||
Порядок прохода: сначала перечислить фактическое (env-ключи, маршруты,
|
||||
`postconf`-настройки), потом искать каждый пункт в README — так находится и
|
||||
неверное, и **отсутствующее**.
|
||||
`postconf`-настройки), потом искать каждый пункт в README / `architecture.md` —
|
||||
так находится и неверное, и **отсутствующее**. До закрытия D9 для чеклиста
|
||||
README допустима сверка с `specification.md` §10–11; после D9 — только с §1
|
||||
этого файла.
|
||||
|
||||
---
|
||||
|
||||
@@ -230,7 +257,8 @@ DNS-карточка домена); прогрев IP; смысл фиксиро
|
||||
«на живом контейнере так делать не надо, потому что SQLite в WAL». Заодно
|
||||
упомянуть, что `manifest.json` после успешного восстановления потребляется.
|
||||
|
||||
**D4. Точечные правки.** Находки 5, 7, 8, 11: баннер статуса и ссылки; комментарий
|
||||
**D4. Точечные правки.** Находки 5, 7, 8, 11: баннер статуса и ссылки (убрать
|
||||
ссылку на `specification.md` — после D9 продукт в `product.md`); комментарий
|
||||
в шапке compose про `.env`; строка про 587; бамп тега образа (делается в
|
||||
релизном коммите, не раньше).
|
||||
|
||||
@@ -245,17 +273,36 @@ DNS-карточка домена); прогрев IP; смысл фиксиро
|
||||
|
||||
**D7. Регресс-защита (см. раздел 5).**
|
||||
|
||||
**D8. Новые документы: `docs/architecture.md` и `docs/development.md`.**
|
||||
Пишутся с нуля (в разделе 3 их нет — это не расхождение с кодом, а
|
||||
отсутствовавший артефакт). `architecture.md` сверяется тем же методом, что и
|
||||
остальное (раздел 2): по факту компоновки образа и кода, не по памяти.
|
||||
`development.md` фиксирует уже существующий, но нигде не описанный процесс
|
||||
(Go локально / полный цикл на dev-сервере для Docker-зависимых изменений).
|
||||
**D8. Новые документы: `architecture.md` и `development.md`.** Пишутся с нуля и
|
||||
перенимают техническую часть ТЗ (§4–7, §9, §12) в форму as-built / процесса.
|
||||
`architecture.md` сверяется методом из раздела 2 — по коду, не по памяти.
|
||||
`development.md` фиксирует воспроизводимый процесс (Go локально / e2e /
|
||||
dev-сервер).
|
||||
*Готово, когда:* `architecture.md` перечисляет все managed-процессы из
|
||||
[build/supervisord.conf](../build/supervisord.conf) и путь письма через
|
||||
milter-цепочку без противоречий коду; `development.md` позволяет с нуля
|
||||
повторить локальную сборку + прогон тестов и понять, когда нужен
|
||||
dev-сервер, не заглядывая в память проекта.
|
||||
повторить локальную сборку + прогон тестов и понять, когда нужен dev-сервер,
|
||||
не заглядывая в память проекта и не открывая `specification.md`.
|
||||
|
||||
**D9. Вывод `specification.md` из обращения (после D1–D8).** Закрывает цель
|
||||
плана: живой ТЗ больше не нужен.
|
||||
1. Создать `docs/product.md` — §1–3, §4.1 (см. карту миграции в §1).
|
||||
2. Дополнить [security.md](security.md) разделом «Обязательные требования» —
|
||||
самодостаточный чеклист из бывшего §7.6 (setup-link, SASL, сессии,
|
||||
rate-limit логина, `html/template`, не-root и т.д.), без отсылки «см. ТЗ».
|
||||
3. Убедиться, что D1–D4 и D8 покрыли всё из §8–11, что должно жить в README /
|
||||
`architecture.md` (пройти карту миграции построчно).
|
||||
4. Перенести `specification.md` → `docs/archive/specification-v1.0.md` без
|
||||
правок текста; в начале архива — одна строка: «исторический снимок v1.0,
|
||||
не источник истины».
|
||||
5. Обновить ссылки во всём репозитории: `progress.md` (убрать «ТЗ:
|
||||
specification.md», заменить на `product.md` + `architecture.md`),
|
||||
`implementation-plan.md` и `roadmap.md` («Основа» → `product.md`),
|
||||
`security.md`, `README.md` (баннер D4 — не на ТЗ). `rg specification\.md`
|
||||
по репо — только архив и CHANGELOG/история.
|
||||
*Готово, когда:* в `docs/` нет `specification.md`; новый агент после `/clear`
|
||||
может понять продукт, устройство, безопасность и процесс разработки, не
|
||||
открывая архив.
|
||||
|
||||
---
|
||||
|
||||
@@ -270,16 +317,18 @@ dev-сервер, не заглядывая в память проекта.
|
||||
новом недокументированном ключе. Ловит самый частый класс расхождений
|
||||
(находка 3) без ручного прохода. Границу «внутренних» ключей задать явным
|
||||
списком-исключением в самом тесте.
|
||||
3. **Перед каждым тегом** — короткий проход по разделу 2 этого файла (семь
|
||||
источников истины), а не полная ревизия текста.
|
||||
3. **Перед каждым тегом** — короткий проход по разделу 2 (источники истины в
|
||||
коде + README + `architecture.md` + `product.md`), а не полная ревизия текста
|
||||
и не сверка с архивным ТЗ.
|
||||
|
||||
---
|
||||
|
||||
## 6. Гейт релиза
|
||||
|
||||
Документационный проход — часть того же гейта, что e2e (C.4) и ревизия
|
||||
безопасности (D.5): **D1–D6 закрыты до тега**. D7 и D8 — желательны, но тег не
|
||||
блокируют: D8 не покрывает пробел против ТЗ (архитектура/разработка не входят
|
||||
в обязательную поставку), поэтому может тянуться в фон после релиза. Находки,
|
||||
обнаруженные позже, дописываются сюда, а не исправляются молча: этот файл —
|
||||
журнал состояния документации, а не одноразовый список дел.
|
||||
безопасности (D.5): **D1–D6 и D9 закрыты до тега**. D7 желателен, но тег не
|
||||
блокирует. **D8** — обязателен до D9 (архитектура должна существовать до
|
||||
миграции); D8 один тег не блокирует, если D9 отложен, но **полное закрытие
|
||||
плана (= вывод specification) — только D1–D9 вместе**. Находки, обнаруженные
|
||||
позже, дописываются сюда, а не исправляются молча: этот файл — журнал
|
||||
состояния документации, а не одноразовый список дел.
|
||||
|
||||
Reference in New Issue
Block a user