Экспорт: ключ архива из секрета аккаунта через HKDF, заголовок ровно 65 байт (magic, версия, соль, 32 сырых байта отпечатка владельца, iv) и он же целиком AAD шифротекста. Ника владельца в файле нет. Импорт сверяет отпечаток до расшифровки, сливает идемпотентно по id, а записи peers берёт только для ников, которых в локальном TOFU ещё нет: архивом доверие к ключу не перебить. Настройки: устройства с датой и пометкой «это устройство», «занято N МБ», кнопка «экспортировать» в подтверждении выхода и в подтверждении входа под другим ником — долг этапа 1 и обещание ADR-029 закрыты. Лента: страницы по 50 с подгрузкой вверх без прыжка прокрутки; новая страница вставляется, а не пересобирает ленту. ADR-050: импорт не перезаписывает лежащую запись — у своей есть состояние отправки, которого в архиве нет. ADR-054: архив — недоверенный ввод. Ревью собрало архивы с ts вне диапазона Date, мусорным lastId, ником с bidi-переопределением и roomId с обходом пути: каждый из них навсегда ломал ленту или счётчик. Теперь форма ника, roomId, id, ts и автора проверяется, а lastId из файла не читается вовсе. ADR-051, 052, 053: тексты и кнопки, устройства и место, страницы ленты без виртуализации. Приёмка: формат сверен побайтно на модулях, скачанных с боевого сервера, — смещения заголовка, отпечаток сырыми байтами, новые соль и iv на каждый экспорт, подмена любого байта заголовка ломает расшифровку, чужой секрет не открывает, семь видов битых файлов отвергнуты. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DbCjVfTFq4ZFG8juD45YJ
3.9 KiB
ADR-051: Кнопка «экспортировать» в подтверждениях и тексты архива
Контекст
История на устройстве — единственная копия, и стирают её два экрана: «выйти» в настройках и вход под другим ником (ADR-029). docs/ui.md держит кнопку «экспортировать» только в первом из них, потому что второго ADR-029 коснулся тогда, когда экспорта не существовало вовсе, и прямо пообещал: «когда он появится, кнопка придёт сюда тем же порядком — сначала docs/ui.md». Экспорт появился.
Ко второму экрану вопросов нет: секрет прежнего аккаунта лежит на устройстве, а сессия экспорту не нужна — архив собирается из IndexedDB (ADR-014).
Тексты раздела «история» перечислены, но двух вещей в них нет. «добавлено N сообщений» не сходится с числом: при одном сообщении получается «добавлено 1 сообщений». И отказ, который не про файл: истории не прочитать, места на устройстве нет, ключей аккаунта нет — в перечне ответов такого нет, а показывать его надо: молчащая кнопка «экспортировать» перед стиранием истории — худший из возможных исходов.
Решение
- Подтверждение входа под другим ником получает третью кнопку: «экспортировать», «удалить», «отмена». Порядок и место — как у подтверждения выхода: «экспортировать», «выйти», «отмена».
- Экспорт подтверждение не закрывает: архив скачался, а стирать историю или нет — отдельное решение того же человека.
- Начальный фокус в обоих подтверждениях — на «экспортировать»: с неё безопасно начинать.
- «добавлено N сообщений» согласуется с числом: «добавлено 1 сообщение», «добавлено 2 сообщения», «добавлено 5 сообщений».
- «Тексты состояний» получают две строки: «экспорт не удался» — архив не собрался; «импорт не удался» — разобранный архив не дошёл до базы. Порча самого файла и чужой архив говорят о себе своими словами, они уже в перечне.
- Всё перечисленное записано в
docs/ui.md: «Вход и регистрация», «Настройки», «Тексты состояний».
Следствия
- Единственная копия истории не исчезает без предложения сохранить её ни на одном экране.
- Кнопок в подтверждении три, и в один ряд они помещаются не всегда: «экспортировать» в моноширинном шрифте шире трети колонки настроек, а насколько — решает системный шрифт платформы. Панель переносит их сама, цель нажатия остаётся 44 px.
- Обещание ADR-029 закрыто.