Сервер: миграция 001 со всей схемой storage.md, store на modernc.org/sqlite (WAL, foreign_keys, один писатель), фоновая чистка раз в час, argon2id с параметрами ADR-021 и сверкой constant-time, сессии по SHA-256 токена, cookie bare_session, глобальная проверка Origin, девять эндпоинтов аккаунта. Ник в журнал не попадает: для /api/ пишется шаблон маршрута. Клиент: crypto.js по crypto.md построчно — мастер из пароля, два независимых ключа из мастера, ключевой блоб с ником в AAD, отпечаток от сырой точки; db.js со всеми хранилищами версии 1; экран входа и регистрации, настройки со сменой пароля, выходом и удалением аккаунта. Пароль не покидает клиент: проверено на боевом сервере — ни пароля, ни priv.d ни в одном теле запроса, вход на втором устройстве даёт тот же отпечаток. ADR-027: код internal для 500, причина только в журнале. ADR-028: тексты состояний клиента сведены в ui.md. ADR-029: вход под другим ником стирает историю только после подтверждения. ADR-030: верхняя граница итераций KDF, проверка границ на обеих сторонах. ADR-031: служебный выход перед повторным входом не заканчивает сеанс. ADR-032: каталог состояния 0700, файлы базы 0600. Прямые зависимости: modernc.org/sqlite, golang.org/x/crypto. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DbCjVfTFq4ZFG8juD45YJ
1.8 KiB
1.8 KiB
ADR-027: Код internal для сбоя на стороне сервера
Контекст
ADR-026 сделал перечень кодов ошибок в protocol.md исчерпывающим: клиент разбирает поле error, а не статус. Кода для 500 в перечне нет, а сбои существуют — недоступная база, ошибка записи. Этап 1 упёрся в это на первом же запросе к хранилищу: отвечать телом без кода нельзя, придумывать код в коде молча — тоже.
Решение
- Сбой на стороне сервера —
500с кодомinternal. Сообщение общее и не зависит от причины. - Причина уходит только в журнал сервера: ни текст ошибки базы, ни имена таблиц, ни ник клиенту не показываются. Наружу — код и статус.
- Код добавлен в перечень «Коды ошибок»
protocol.mdи в общие правила. internal— не ветка протокола, а признак поломки: ни один сценарий клиента на него не рассчитывает, повтор запроса допустим.
Следствия
- Перечень кодов снова исчерпывающий: у любого ответа сервера есть разбираемый код.
- Оператор видит причину в
journalctl, клиент — нет. 500в журнале означает ошибку в коде или в окружении и разбирается, а не считается нормой.