Спецификации 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-063 — ACK уходил по одному на конверт: получатель в оживлённой комнате выедал ведро лимита и не мог даже выйти из комнаты.
ADR-037 — противоречие в самих спецификациях: roomId вплетён в заворачивание ключа, а заворачивание идёт до запроса, которым его выдавал сервер.
Проверено
Приёмка каждого этапа гонялась против боевого сервера, не только локально. Сборка воспроизводима: свежий клон, git checkout v1, те же флаги — бинарь байт в байт совпадает с тем, что лежит на сервере.
Пуши на iPhone и Android, клик по системному уведомлению, beforeinstallprompt, iOS-баннер, Firefox и Safari. Автоматика гоняла только Chrome. Чеклист — в docs/plan.md, этап 4.
Спецификации `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
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Спецификации
ADR-015…024и реализация всех шести этаповdocs/plan.md. Каждый этап — отдельный коммит, каждый задеплоен на https://bare.xmatic.team по ходу работы.Этапы
ae55c8432717cb597c55363a7a1e05586218f67f4a0c87847.bare, пагинацияdb45978Что получилось
5253 строки Go и 6740 строк клиентского JS без сборки, 131 тест, ровно три прямые зависимости (
modernc.org/sqlite,golang.org/x/crypto,webpush-go). Клиент безinnerHTML, inline-стилей, inline-скриптов и внешних ресурсов: CSPdefault-src 'self'без исключений.ADR: добавлено 39, с 025 по 063
Не косметика. Те, что закрыли настоящие дыры:
idконверта и мог перезаписать им сообщение в чужой истории, вплоть до стирания собственного присланного.Room.keyзапись, завёрнутую посторонним аккаунтом; TOFU молчал, потому что ник незнакомый, и комната уезжала на ключ сервера.endpointподписки, выбранный браузером; проверка «только https» обходилась редиректом.roomIdвплетён в заворачивание ключа, а заворачивание идёт до запроса, которым его выдавал сервер.Проверено
Приёмка каждого этапа гонялась против боевого сервера, не только локально. Сборка воспроизводима: свежий клон,
git checkout v1, те же флаги — бинарь байт в байт совпадает с тем, что лежит на сервере.Не проверено
Пуши на iPhone и Android, клик по системному уведомлению,
beforeinstallprompt, iOS-баннер, Firefox и Safari. Автоматика гоняла только Chrome. Чеклист — вdocs/plan.md, этап 4.🤖 Generated with Claude Code
https://claude.ai/code/session_015DbCjVfTFq4ZFG8juD45YJ