Files
selfpost/docs/progress.md
T
mix e51917fcb5 docs: decide item B.1 — persistent sessions with a sliding idle window
Sessions move from the in-memory map to a `sessions` table (migration
0002), so a restart, a redeploy or a restore from a full backup no longer
signs the administrator out. The row holds a SHA-256 of the token rather
than the token itself: a stolen database file or backup archive cannot be
replayed into a login, while the browser that still holds the cookie keeps
working across a restore.

The 12-hour absolute TTL becomes a sliding 7-day idle window, configurable
through PANEL_SESSION_IDLE_DAYS (whole days, mirroring
SEND_LOG_RETENTION_DAYS). No absolute cap: for an administrator who visits
regularly the session lasts indefinitely, which is the accepted trade-off.
The four `every 5s` monitoring fragments deliberately do not renew it —
otherwise a forgotten open tab would hold the session open forever and the
window would mean "seven days without an open tab" rather than "seven days
without the administrator".

Decision only; no code yet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 22:04:25 +03:00

45 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Прогресс реализации SelfPost
Живой трекер состояния. **Переживает `/clear`** — читается первым при возобновлении работы.
План (открытые вопросы + опциональные фазы): [implementation-plan.md](implementation-plan.md).
ТЗ: [specification.md](specification.md). История релизов: [CHANGELOG.md](../CHANGELOG.md).
История сделанного по фазам (0→13, все закрыты) — в `git log` и в CHANGELOG, здесь не дублируется.
## Как возобновить после сброса контекста
1. Прочитать этот файл (текущее состояние, что дальше).
2. Открыть `implementation-plan.md` — там нерешённые вопросы, принятые риски и опциональная линия 2.x.x (Фаза O1+).
3. При необходимости — детали в `specification.md`.
4. Продолжить с пункта «Следующий шаг».
## Модель по типу работы
Правило: безопасность / инфра / риск-критичное → **Opus**; UI / документация / бойлерплейт → **Sonnet**; тривиальная механика → **Haiku**.
## Коммиты
Коммит на **каждом осмысленном шаге** (не каждое сохранение файла, но и не только конец фазы): рабочий под-функционал, зелёная сборка, конец фазы. Минимум — один коммит на закрытую фазу + промежуточные на связные под-шаги. Ветка `main` (если пользователь не попросит отдельную). Push/PR — только по явной команде. Сообщение коммита завершается трейлером `Co-Authored-By: Claude <модель> <noreply@anthropic.com>` — с той моделью, которая этот шаг делала (на момент Фазы 14 — `Claude Opus 5`).
На каждом таком шаге — запись в [CHANGELOG.md](../CHANGELOG.md) под `[Unreleased]` (формат Keep a Changelog). При явном решении зарезать версию — секция `[Unreleased]` переименовывается в `[X.Y.Z] - дата`, заводится новая пустая `[Unreleased]`. Тег/пуш образа — только по явному запросу (см. workflow release.yml).
## Протокол закрытия фазы/крупного шага
Перед `/clear` в конце каждого законченного шага Claude:
1. Обновляет этот файл: «Текущее состояние» → что изменилось, что дальше.
2. Проверяет применимые критерии «Готово, когда…».
3. Дописывает `CHANGELOG.md` под `[Unreleased]`.
4. Делает финальный коммит шага.
---
## Текущее состояние
- **Выполнено и принято:** базовый линейный план 0→11 (v1.0; аудит безопасности ТЗ 7.6 — полное соответствие), Фаза 12 (UI/UX), Фаза 13 (страница `/status`, DNS-проверки домена) и Фаза 14 (security-заголовки, проверка origin, cookie `__Host-` + обнаружение дублей, документация про `/data/setup-token`). Что именно сделано — в `git log` и `CHANGELOG.md`, здесь не дублируется.
- **Решено, но ещё не реализовано:** пункт **B.1** плана — сессии переезжают в SQLite (скользящий срок бездействия 7 дней, `PANEL_SESSION_IDLE_DAYS`, опросы не продлевают, смена пароля разлогинивает всех). Параметры согласованы полностью, кода нет: делать отдельным шагом.
- **Дальше — то, что перечислено в `implementation-plan.md`:** открытые вопросы разделов B–D (надёжность и эксплуатация, e2e в CI, указатель на объём 2.x) и принятые риски раздела A (`POST` без `Sec-Fetch-Site`/`Origin` пропускается, токенов нет); опциональная **Фаза O1+** (входящий релей, линия 2.x.x, требует согласования).
- **Прод:** `selfpost.example.com`, реальный Let's Encrypt сертификат, живой e2e (DKIM/SPF pass). Контейнер там всё ещё на образе v1.0 — Фаза 14 в него не выкатывалась. При апгрейде: админа один раз разлогинит (сменилось имя cookie), а от reverse-proxy требуется передача исходного `Host` (Apache-фрагмент из `deploy/` это делает).
## Рабочая петля (dev loop) — ВАЖНО
Локально (Windows, `<repo>`) **нет Go и Docker** — только редактирование и git. Вся сборка/тесты идут на dev-сервере `selfpost.example.com` (Debian 12 bookworm, тот же, что базовый образ; провижён под разработку). Цикл: править локально → залить дерево на сервер → `go build`/`go vet`/`docker build`/тесты там. `rsync` в локальном git-bash нет, поэтому дерево едет tar'ом по ssh: `tar -czf - --exclude=.git . | ssh root@selfpost.example.com 'rm -rf /root/selfpost-src && mkdir -p /root/selfpost-src && tar -xzf - -C /root/selfpost-src'`; Go на сервере — в `/usr/local/go/bin` (не в `PATH` по умолчанию); образ — `docker build -f build/Dockerfile -t selfpost:dev --build-arg VERSION=dev .`. Источник истины и git-история — локальный репозиторий; сервер — только исполнитель сборки/тестов. Подключение: `ssh root@selfpost.example.com` (по ключу).