Этап 0: скелет сервера, статика из embed, деплой на bare.xmatic.team

Один бинарь на stdlib, ноль зависимостей: подкоманды serve, vapid, version;
статика из embed с ETag и Cache-Control: no-cache; /healthz; заголовки
безопасности ADR-021 на всех ответах, включая ошибки; лимит тела 32 КиБ.
Путь в логе — в percent-форме: подделать строку журнала запросом нельзя.
Ни IP, ни ника, ни query в логах нет.

Клиент — знак «Скобы» и слово bare: без script-тегов, inline-стилей
и внешних ресурсов.

ADR-025: go:embed не выходит за каталог пакета, поэтому объявление
статики живёт в корне модуля, а клиент остаётся в web/.
ADR-026: 413 отдаётся кодом too_large, неподдерживаемый метод — 404;
оба добавлены в перечень protocol.md.

Сервер: пользователь bare, /opt/bare, /var/lib/bare, /etc/bare/env 0600,
systemd-юнит, nginx с сертификатом certbot (плагин nginx, как у соседей).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015DbCjVfTFq4ZFG8juD45YJ
This commit is contained in:
2026-08-22 11:49:11 +03:00
co-authored by Claude Opus 5
parent ae55c846aa
commit 32717cb7dd
16 changed files with 784 additions and 2 deletions
@@ -0,0 +1,17 @@
# ADR-026: Код `too_large` и 404 на неподдерживаемый метод
## Контекст
Этап 0 обнажил два места, где код знает больше протокола. Первое: `413` описан в общих правилах (`ADR-021`, «тело запроса — до 32 КиБ»), но кода ошибки для него в перечне `protocol.md` нет, а сервер уже отдаёт `{"error": "too_large"}`. Второе: `POST` к известному пути статики отвечает `404 not_found`; в перечне правил есть только «неизвестный путь — `404 not_found`», решение про метод жило комментарием в коде.
## Решение
- `413` отдаётся с кодом `too_large`. Код добавлен в перечень «Коды ошибок» `protocol.md`, строка про лимит тела уточнена до `413 too_large`.
- Неподдерживаемый метод на известном пути — тоже `404 not_found`. Кода `405` в протоколе нет и не появится: клиент ходит по фиксированному набору маршрутов, а лишний код — лишняя ветка у обеих сторон.
- Тело ошибки в форме `{"error", "message"}` собирает `internal/api`; остальные пакеты пользуются его хелпером, чтобы коды не расходились между пакетами.
## Следствия
- Клиент разбирает `error` по перечню из `protocol.md`, и перечень исчерпывающий.
- Отсутствие `405` означает, что перебор методов не отличается от перебора путей — снаружи виден только `404`.
- `internal/web` импортирует `internal/api`; обратной зависимости нет.