Bare v1: реализация всех шести этапов плана #2

Merged
halofourteen merged 8 commits from release/v1 into main 2026-08-23 07:17:41 +03:00
halofourteen commented 2026-08-23 07:17:22 +03:00 (Migrated from github.com)

Спецификации ADR-015…024 и реализация всех шести этапов docs/plan.md. Каждый этап — отдельный коммит, каждый задеплоен на https://bare.xmatic.team по ходу работы.

Этапы

коммит этап
ae55c84 ADR-015…024 и спецификации v1
32717cb 0 — скелет сервера, статика из embed, деплой
597c553 1 — аккаунты: argon2id, сессии, ключевой блоб
63a7a1e 2 — чат 1:1: устройства, очередь, SSE, шифрование
0558621 3 — TOFU и комнаты: ключ комнаты, атомарный rekey
8f67f4a 4 — PWA и пуши: service worker, Web Push с VAPID
0c87847 5 — история: экспорт и импорт .bare, пагинация
db45978 6 — закалка: лимиты ADR-021, аудит модели угроз

Что получилось

5253 строки Go и 6740 строк клиентского JS без сборки, 131 тест, ровно три прямые зависимости (modernc.org/sqlite, golang.org/x/crypto, webpush-go). Клиент без innerHTML, inline-стилей, inline-скриптов и внешних ресурсов: CSP default-src 'self' без исключений.

ADR: добавлено 39, с 025 по 063

Не косметика. Те, что закрыли настоящие дыры:

  • ADR-034 — собеседник знал открытый id конверта и мог перезаписать им сообщение в чужой истории, вплоть до стирания собственного присланного.
  • ADR-039 — сервер подставлял в Room.key запись, завёрнутую посторонним аккаунтом; TOFU молчал, потому что ник незнакомый, и комната уезжала на ключ сервера.
  • ADR-041 — долг по rekey жил только в живом событии: владелец, офлайн в момент выхода участника, не узнавал о нём никогда.
  • ADR-047 — сервер ходит на endpoint подписки, выбранный браузером; проверка «только https» обходилась редиректом.
  • ADR-058 — «выйти на других устройствах» не обрывал уже открытый SSE.
  • ADR-059 — участник, пропустивший офлайн два rekey подряд, навсегда терял промежуточный ключ.
  • ADR-063 — ACK уходил по одному на конверт: получатель в оживлённой комнате выедал ведро лимита и не мог даже выйти из комнаты.
  • ADR-037 — противоречие в самих спецификациях: roomId вплетён в заворачивание ключа, а заворачивание идёт до запроса, которым его выдавал сервер.

Проверено

Приёмка каждого этапа гонялась против боевого сервера, не только локально. Сборка воспроизводима: свежий клон, git checkout v1, те же флаги — бинарь байт в байт совпадает с тем, что лежит на сервере.

sha256  cec3b048bdf277fbe0012f306304452572a0ad4bee77010a021a48b42a04d374
тег     v1 → db45978b1640a8a54f42e6ebc1413e1b5a023cd3

Не проверено

Пуши на iPhone и Android, клик по системному уведомлению, beforeinstallprompt, iOS-баннер, Firefox и Safari. Автоматика гоняла только Chrome. Чеклист — в docs/plan.md, этап 4.

🤖 Generated with Claude Code

https://claude.ai/code/session_015DbCjVfTFq4ZFG8juD45YJ

Спецификации `ADR-015…024` и реализация всех шести этапов `docs/plan.md`. Каждый этап — отдельный коммит, каждый задеплоен на https://bare.xmatic.team по ходу работы. ## Этапы | коммит | этап | |---|---| | `ae55c84` | ADR-015…024 и спецификации v1 | | `32717cb` | 0 — скелет сервера, статика из embed, деплой | | `597c553` | 1 — аккаунты: argon2id, сессии, ключевой блоб | | `63a7a1e` | 2 — чат 1:1: устройства, очередь, SSE, шифрование | | `0558621` | 3 — TOFU и комнаты: ключ комнаты, атомарный rekey | | `8f67f4a` | 4 — PWA и пуши: service worker, Web Push с VAPID | | `0c87847` | 5 — история: экспорт и импорт `.bare`, пагинация | | `db45978` | 6 — закалка: лимиты ADR-021, аудит модели угроз | ## Что получилось 5253 строки Go и 6740 строк клиентского JS без сборки, 131 тест, ровно три прямые зависимости (`modernc.org/sqlite`, `golang.org/x/crypto`, `webpush-go`). Клиент без `innerHTML`, inline-стилей, inline-скриптов и внешних ресурсов: CSP `default-src 'self'` без исключений. ## ADR: добавлено 39, с 025 по 063 Не косметика. Те, что закрыли настоящие дыры: - **ADR-034** — собеседник знал открытый `id` конверта и мог перезаписать им сообщение в чужой истории, вплоть до стирания собственного присланного. - **ADR-039** — сервер подставлял в `Room.key` запись, завёрнутую посторонним аккаунтом; TOFU молчал, потому что ник незнакомый, и комната уезжала на ключ сервера. - **ADR-041** — долг по rekey жил только в живом событии: владелец, офлайн в момент выхода участника, не узнавал о нём никогда. - **ADR-047** — сервер ходит на `endpoint` подписки, выбранный браузером; проверка «только https» обходилась редиректом. - **ADR-058** — «выйти на других устройствах» не обрывал уже открытый SSE. - **ADR-059** — участник, пропустивший офлайн два rekey подряд, навсегда терял промежуточный ключ. - **ADR-063** — ACK уходил по одному на конверт: получатель в оживлённой комнате выедал ведро лимита и не мог даже выйти из комнаты. - **ADR-037** — противоречие в самих спецификациях: `roomId` вплетён в заворачивание ключа, а заворачивание идёт до запроса, которым его выдавал сервер. ## Проверено Приёмка каждого этапа гонялась против боевого сервера, не только локально. Сборка воспроизводима: свежий клон, `git checkout v1`, те же флаги — бинарь байт в байт совпадает с тем, что лежит на сервере. ``` sha256 cec3b048bdf277fbe0012f306304452572a0ad4bee77010a021a48b42a04d374 тег v1 → db45978b1640a8a54f42e6ebc1413e1b5a023cd3 ``` ## Не проверено Пуши на iPhone и Android, клик по системному уведомлению, `beforeinstallprompt`, iOS-баннер, Firefox и Safari. Автоматика гоняла только Chrome. Чеклист — в `docs/plan.md`, этап 4. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_015DbCjVfTFq4ZFG8juD45YJ
Sign in to join this conversation.