Files
LumaWeb/docs/decisions/0000-scope.md
T
wt d91103ea1c S00-001: Approve the Web scope passport after independent security review
Changes: Accept ADR 0000 and record the independent reviewer, acceptance findings and handoff. Confirm native exclusion reasons, retained Web obligations, conditional push lifecycle and provider secret/metadata boundaries; transition S00-001 through the review CLI.
Validation: Reviewed executor commit d5ed7eaaed and its message against scope and evidence. python3 experiments/0000-scope/check.py passed ten IDs, seven states and four negative mutations. make check passed validation and all 66 tooling tests. No live browser/provider integration or crypto implementation was tested or accepted.

Task: S00-001
Agent: auto-security-bff4cfd4d38e
Role: security
Action: review
Status: done

Task title: Утвердить Web-профиль
2026-10-15 01:03:56 +07:00

95 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR 0000: Паспорт scope Luma Web
- Status: accepted — независимое security review S00-001; evidence: `state/evidence/S00-001-review.md`.
- Task: S00-001
- Date: 2026-10-15
- Decision owner: auto-orchestrator-48aab142ecde, orchestrator
- Reviewer: auto-security-bff4cfd4d38e, security, 2026-10-15
## Вход, результат и критерии
Вход: неизменяемые `specs/tz_clear.md` (§3, §20, §21, §27; GEN-005, GEN-006, WEB-002), `specs/uikit_clear.md`, applicability из `planning/requirements.json` и Web-профиль основы. Результат: один паспорт Web-scope с причинами исключений и перечнем внешних сервисов. Проверка: исключённые ID полностью совпадают с реестром, у каждого есть содержательная причина, lifecycle не обещает closed-tab XMPP или постоянное медиа через push. Прямых зависимостей и ранее принятых ADR нет; schemas из S01 пока не приняты.
## Решение и объём
Реализуется браузерное приложение для телефона и компьютера: compact navigation и wide sidebar/detail, keyboard/IME, accessibility, safe areas и адаптивный UI Kit. Desktop native package, Android native package, tray, foreground services, APNs/Android SDK и companion/Watch не входят в эту основу. Браузер на Android относится к Web и сохраняет Web-ограничения.
Из 221 ID реестр относит 211 к Web и 10 к out_of_scope. Все 211 остаются обязательствами плана, а не отчётом о готовности. Общие cross-platform требования применяются в Web-контексте; native-примеры UI Kit не исключают общую семантику, accessibility, tokens или touch-сценарии.
Базовый Web-объём сохраняет несколько конфигураций аккаунтов и один активный XMPP-контекст; login/logout/switch, контакты/presence, личные чаты/self-chat, MUC, текст/replies/reactions/correction/retraction/local deletion, selection/forwarding, OMEMO legacy и OMEMO 2 с доверием устройствам, файлы/фото/видео/музыку/voice/video notes/геоточки, локальную историю/MAM/Carbons/receipts/read state, личные аудио-/видеозвонки и их историю, аватары, уведомления/app lock, доступную защищённую биометрию и диагностику сервера.
За базовым объёмом остаются регистрация XMPP-аккаунтов, восстановление серверного пароля, групповые звонки, MIX/каналы, боты, платежи, истории, live location, полнотекстовый поиск всей истории и обязательная одновременная online-сессия всех аккаунтов (§3.2). Развёртывание XMPP-провайдера не является функцией клиента; необходимый push/relay — отдельный поставляемый либо явно подключённый компонент решения.
### Исключённые ID и сохранённые Web-обязательства
| Excluded ID | Причина исключения из этой основы | Web-замена / сохранённая часть |
| --- | --- | --- |
| ACC-003 | Настройка native TCP host/port, STARTTLS/direct TLS и native discovery не является браузерным транспортом. | ACC-004/005: WSS endpoint с видимым доменом и явным выбором неизвестного сервера. |
| NET-002 | Native DNS discovery и ручные параметры транспорта исключены. ID реестра исключён целиком, но его Web-оговорка остаётся обязательной. | WSS endpoint утверждается для выбранного сервера; ACC-004 и NET-001 сохраняются. |
| DESK-001 | Tray, native автозапуск и различие native hide/window quit относятся к устанавливаемому Desktop. | WEB-001/002: различать активную, скрытую и закрытую страницу. |
| DESK-002 | Живой native фоновый процесс и его incoming calls не поставляются браузерной основой. | WEB-002/003: уведомление и открытие страницы с проверкой актуальности вызова. |
| DESK-003 | Native sleep/wake и tray call icon не являются Web-интеграцией. | Web reconnect и push logout/revoke остаются по NET, PUSH и WEB; tray отсутствует. |
| AND-001 | Native Android push/call delivery и выбор системного provider требуют Android-приложения. | Browser Web Push с permission, gateway и проверенной регистрацией. |
| AND-002 | Native lifecycle/permissions и системный фоновый режим Android находятся вне Web-target. | WEB-001/002: скрытая страница может быть приостановлена; фонового socket SLA нет. |
| AND-003 | Android foreground/call service и управление ongoing call из native notification не поставляются. | Звонок в живой Web-сессии при доступных media permissions, без гарантии closed-tab call. |
| AND-004 | Force stop и native battery lifecycle проверяются у Android-приложения, не у этой основы. | Denied permissions, offline, browser termination и sleep требуют честной Web-деградации. |
| STORE-002 | Native secure vault и device key wrapping не предоставляются браузерным storage. | STORE-003/004: password в памяти, повторный вход, отдельное решение crypto unlock и честные quota/eviction. |
## Lifecycle и честные capability states
Закрытая страница не считается постоянно подключённой XMPP-сессией. Service worker notification не гарантирует непрерывный microphone, медиазвонок или автоматический показ полноэкранного incoming UI (WEB-002). Установленная PWA сохраняет эти ограничения. Скрытая страница может быть заморожена или выгружена; состояние connection/call после возвращения сверяется с реальностью (WEB-001). Push может вызвать обработку события/уведомление, но не заменяет постоянно живой socket. После перехода из уведомления выполняются unlock/login при необходимости, синхронизация и проверка срока/состояния вызова (WEB-003).
Таблица ниже — нормативные пределы обещаний, не результаты browser/runtime тестов. `conditional` означает только возможность после проверки prerequisites; `not-guaranteed` запрещает гарантию непрерывности; `none` означает отсутствие соответствующего пути.
| State | XMPP session | Push notification | Continuous media | Automatic fullscreen incoming |
| --- | --- | --- | --- | --- |
| foreground | conditional | conditional | conditional | not-guaranteed |
| hidden | not-guaranteed | conditional | not-guaranteed | not-guaranteed |
| closed-tab | none | conditional | none | none |
| browser-terminated | none | not-guaranteed | none | none |
| permission-denied | conditional | none | none | none |
| offline | none | not-guaranteed | none | none |
| logged-out | none | none | none | none |
Строка permission-denied предполагает отказ и notification, и media permissions; XMPP не требует этих разрешений. Logged-out требует disable/revoke регистрации, поздние события не восстанавливают аккаунт. Offline push может быть отложен/истечь, browser termination зависит от ОС/provider; доставки не обещаем. Реальные проверки foreground/hidden/closed-tab/denied/sleep/rotation/logout/stale notification относятся к будущей приёмке интеграции (§20.4).
GEN-005: различать advertised capability, configured integration и verified usable state. Если сервис/permission/registration недоступен, отключать только зависимую функцию с причиной, сохраняя остальные сценарии. Например, отсутствие TURN ограничивает достижимость звонка, upload — вложения, push — фоновые уведомления; наличие server feature само по себе не доказывает работу интеграции.
GEN-006: не обещать гарантированные delivery/read, отзыв чужих копий, работу закрытого процесса или скрытие metadata. TLS, OMEMO payload, file encryption, DTLS-SRTP, local protection и UI lock имеют разные границы. Gateway не получает decrypted messages или file keys; plaintext fallback, decrypting proxy и обход TLS/CORS недопустимы.
## Внешние providers и границы данных
Ни vendor, ни рабочий URL, ни SLA здесь не выбраны. Это обязательный inventory для topology S00-008 и последующей интеграции; наличие строки не означает подключённый сервис.
| Сервис / provider | Требуемая роль и публичная конфигурация | Данные / секреты и деградация |
| --- | --- | --- |
| HTTPS hosting / origin | Поставка Web assets и service worker через доверенный origin. | Видит сетевые metadata; не получает пароль/ключи через analytics. Hosting и release channels ещё не утверждены. |
| XMPP provider + WSS endpoint | Auth, stanza routing, capability discovery, MUC/MAM/Carbons и поддержанные XEP. Домен endpoint виден пользователю. | Пароль используется только выбранным transport auth; OMEMO plaintext серверу недоступен. Сервер видит routing metadata. При отсутствии WSS соединение недоступно. |
| HTTPS upload provider | Upload slot, разрешённые origin/CORS, size/expiry policy. | Encrypted attachment bytes; file key передаётся в защищённом сообщении. Ошибка/quota отключает upload с объяснением. |
| STUN/TURN provider | NAT traversal/relay для WebRTC; публичные server URLs в runtime config. | IP/время/объём relay видимы provider; TURN secrets отдельно, без committed примеров. Недоступность не выдаётся за успешный звонок. |
| XMPP push service / gateway | Связать XMPP enable/disable с браузерной subscription, update/expiry/logout/revoke. | Минимальные registration metadata; без body/file key/password. Gateway private credentials и VAPID private key вне repo/logs. |
| Browser-selected Web Push service | Доставка к user agent, permission и subscription endpoint; это отдельная роль от gateway. | Timing/size metadata видимы provider; subscription — чувствительные данные, не public config. Без permission/registration нет «Push работает». |
| Maps / tiles / geocoding provider | Явно подключённые карты для геоточек, утверждённые endpoints и политика доступа. | Coordinates/IP могут раскрыться provider, требуется минимизация/объяснение; live location исключён. При отсутствии сервиса не выдавать карту за загруженную. |
Публичные URLs и несекретные capabilities идут в runtime config. Password только в памяти; постоянный login/crypto unlock остаётся отдельным ADR S00-007. Browser quota/очистка не эквивалентны hardware-backed vault. Secrets, реальные JID, subscriptions и переписки не входят в fixtures/evidence/environment examples.
## Рассмотренные варианты и первичные источники
Проверено 2026-10-15; sources подтверждают границы механизма, не совместимость конкретных браузеров.
- Выбранный WSS путь: [RFC 7395, §3 и §6](https://www.rfc-editor.org/rfc/rfc7395.html) определяет XMPP WebSocket binding и защиту endpoint через TLS. Native TCP не переносится в Web controls. Браузер проверяет TLS; обход сертификатов не разрешён.
- Альтернатива HTTPS BOSH: [XEP-0206](https://xmpp.org/extensions/xep-0206.html) описывает XMPP поверх BOSH. В этом профиле не требуется и не включается; возможное включение требует отдельного решения по ACC-004.
- Event-driven push: [W3C Push API, introduction и §4](https://www.w3.org/TR/2026/WD-push-api-20261005/) описывает push service, delivery к worker и видимые provider metadata. Working Draft не является обещанием поддержки всех browser features.
- Предел worker lifetime: [W3C Service Workers, §2.1.1](https://www.w3.org/TR/2026/CRD-service-workers-20260917/#service-worker-lifetime) связывает lifetime с обработкой событий и допускает прекращение worker. Вывод для профиля: worker нельзя считать непрерывной XMPP/media-сессией.
- Раздельные push роли: [XEP-0357, §2 и §5](https://xmpp.org/extensions/xep-0357.html) описывает XMPP push service и внешнюю delivery service с отдельным enable. Одного advertised XMPP feature недостаточно.
Отклонены обещание native transport в браузере, «вечная» PWA socket/media-сессия и автоматически подключённые providers. Повод пересмотра — новая утверждённая версия требований или проверяемая platform integration через отдельный ADR/plan change; исходные snapshots сохраняются.
## Проверка, ограничения и следующие решения
Focused experiment: `python3 experiments/0000-scope/check.py` проверяет полное покрытие excluded IDs по canonical registry/specs, содержательные причины и нормативные lifecycle limits; отрицательные мутации подтверждают обнаружение пропуска/ложной closed-tab гарантии. Это проверка паспорта, без сетевой интеграции, browser spike или runtime implementation.
Новых dependencies и library licenses нет. Выбор framework/runtime и проверка лицензий — S00-002; XMPP и crypto libraries/interoperability — S00-003/004; IndexedDB — S00-005; browser/reference matrix и PWA mode — S00-006; unlock — S00-007; конкретная topology/providers — S00-008; совместный gate — S00-009/010. До их принятия отсутствуют browser versions, file/cache/pending limits, performance reference devices, server/client wire-format evidence и release hosting/update policy. Их отсутствие явно ограничивает текущий паспорт и запрещает обещать готовность релиза; для bounded S00-001 эти решения не выбираются.
Shared contracts из реестра остаются задачами S01. Этот паспорт не задаёт новые поля интерфейсов и не меняет план/applicability. Security reviewer проверяет причины, lifecycle, provider data boundaries, scope и evidence перед принятиями coordinator workflow.