[ { "id": "GEN-001", "source": "specs/tz_clear.md", "text": "Одинаковые действия на разных платформах должны иметь одинаковый смысл: «Отправлено», «Доставлено», «Прочитано», локальное удаление и отзыв нельзя интерпретировать по-разному.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "GEN-002", "source": "specs/tz_clear.md", "text": "UI, предметная логика, протоколы, хранение и системные интеграции разделяются устойчивыми интерфейсами. UI не владеет криптографической сессией или активным медиасоединением.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "GEN-003", "source": "specs/tz_clear.md", "text": "Криптография, обработка больших файлов, индексирование и архивная загрузка не должны монопольно занимать поток отображения интерфейса.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "GEN-004", "source": "specs/tz_clear.md", "text": "Все долгие операции имеют состояние выполнения, завершения, ошибки и отмены там, где отмена безопасна. Ошибка не оставляет интерфейс навсегда заблокированным.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "GEN-005", "source": "specs/tz_clear.md", "text": "Недоступная возможность сервера отключает соответствующую функцию с объяснением, сохраняя остальные функции. Поддержка, объявленная сервером, не отображается как уже настроенная интеграция приложения.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "GEN-006", "source": "specs/tz_clear.md", "text": "Приложение не обещает гарантированную доставку, прочтение, удаление чужих копий, работу закрытого процесса или конфиденциальность метаданных, если механизм этого не обеспечивает.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "GEN-007", "source": "specs/tz_clear.md", "text": "Исходные документы, тесты и поставляемая версия приложения должны соответствовать друг другу. Релиз имеет номер версии и журнал изменений.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ACC-001", "source": "specs/tz_clear.md", "text": "Входная форма содержит JID, пароль, показать/скрыть пароль и дополнительные настройки. Пустой JID/пароль не принимаются.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ACC-002", "source": "specs/tz_clear.md", "text": "JID валидируется по выбранному XMPP address preparation; пробелы по краям ввода обрабатываются, resource не смешивается с bare account identity. Пароль не обрезается молча.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ACC-003", "source": "specs/tz_clear.md", "text": "Native-клиенты поддерживают discovery и ручной host/port с STARTTLS/direct TLS. Стандартные порты: 5222 для STARTTLS, 5223 для direct TLS. Порт проверяется как число 1…65535; нечисловой ввод показывает ошибку, а не молча превращается в default.", "applicability": "out_of_scope", "reason": "Native host/port TCP configuration; Web uses ACC-004 WSS." }, { "id": "ACC-004", "source": "specs/tz_clear.md", "text": "Web-клиент использует защищённый WebSocket XMPP endpoint. Форма допускает ввод/выбор WSS endpoint и не обещает прямое использование произвольного TCP host/port браузером. BOSH не обязателен; если включён отдельно, допускается только HTTPS.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ACC-005", "source": "specs/tz_clear.md", "text": "Endpoint discovery не должен незаметно отправлять пароль произвольному стороннему шлюзу. Пользователь видит домен выбранного endpoint; для неизвестной конфигурации требуется явный выбор сервера.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ACC-006", "source": "specs/tz_clear.md", "text": "На время входа показывается progress и блокируется повторная отправка той же формы. После успешного входа открываются локальная история и основной интерфейс. Ошибка оставляет возможность исправить credentials.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ACC-007", "source": "specs/tz_clear.md", "text": "Можно сохранить несколько аккаунтов. Добавление аккаунта делает его активным после успешного входа. Одновременно обязательно только одно активное соединение; неактивные аккаунты не представляются как постоянно online.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ACC-008", "source": "specs/tz_clear.md", "text": "Переключение закрывает/отделяет старый контекст и открывает данные нового. Завершившаяся поздно операция прошлого аккаунта не может записать результат в новый аккаунт или отправить сообщение от его имени.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ACC-009", "source": "specs/tz_clear.md", "text": "При доступных credentials запуск восстанавливает активный аккаунт и локальную историю, затем соединение. Если secrets недоступны/истекли, приложение запрашивает повторный вход без потери сохранённой истории.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ACC-010", "source": "specs/tz_clear.md", "text": "Для каждого устройства создаётся устойчивый уникальный ресурс; одновременный запуск разных устройств одного аккаунта не должен создавать конфликт одинаковых default resources.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ACC-011", "source": "specs/tz_clear.md", "text": "«Выйти» прекращает соединение, unregister/disable применимую push-привязку, удаляет сохранённые credentials текущего аккаунта и очищает его чувствительное session state. Локальную историю можно сохранить.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ACC-012", "source": "specs/tz_clear.md", "text": "Отдельный вариант «Выйти и удалить локальные данные» удаляет историю, suppression, drafts, медиа cache и данные аккаунта в локальном профиле. Удаление OMEMO identity — явно обозначенный вариант со предупреждением о потере доступа к старым encrypted сообщениям; без согласия identity не уничтожается как побочный эффект обычного выхода.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ACC-013", "source": "specs/tz_clear.md", "text": "Удаление локальных данных не называется secure erase и не обещает удаление server archives, exports, backup или чужих копий.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ACC-014", "source": "specs/tz_clear.md", "text": "Перед уходом из аккаунта незавершённые записи/загрузки имеют определённое поведение: отмена либо сохранение безопасного локального результата; нет продолжения отправки от случайного другого аккаунта.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NET-001", "source": "specs/tz_clear.md", "text": "Подключение защищено TLS; проверяются certificate chain и ожидаемое имя сервиса/endpoint согласно используемому транспорту. Insecure HTTP/WS и обход ошибок сертификата не включены в пользовательский стандарт.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NET-002", "source": "specs/tz_clear.md", "text": "Нативный транспорт поддерживает DNS discovery и ручные параметры. В Web используется WSS endpoint, утверждённый для выбранного сервера.", "applicability": "out_of_scope", "reason": "Native transport discovery; Web WSS addressed by ACC-004/NET-001." }, { "id": "NET-003", "source": "specs/tz_clear.md", "text": "Аутентификация выбирает наиболее сильный совместимый объявленный механизм. Приоритет SCRAM-PLUS с доступным channel binding, затем SCRAM-SHA-512/256/1, затем разрешённый защищённым транспортом fallback.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NET-004", "source": "specs/tz_clear.md", "text": "PLUS не имитируется при отсутствии данных реального TLS-канала. В частности, реализации, не имеющие доступа к exporter/binding, выбирают совместимый non-PLUS механизм и корректно отражают это в диагностике.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NET-005", "source": "specs/tz_clear.md", "text": "Проверяются nonce, server proof/signature, параметры challenge и применимые downgrade-protection данные. Для limits на challenge/iterations определяется защитная конфигурация, предотвращающая блокировку клиента недоверенным вводом.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NET-006", "source": "specs/tz_clear.md", "text": "Состояния: отключено, подключение, подключено, восстановление, ошибка/требуется вход. Причина ошибки локализована. Нельзя показывать «Подключено» только по наличию сохранённого аккаунта.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NET-007", "source": "specs/tz_clear.md", "text": "Поддерживаются stream management, carbons, ping и client-state indication при поддержке транспорта/сервера.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NET-008", "source": "specs/tz_clear.md", "text": "Повторное соединение использует ограниченный backoff с jitter, прекращается при явном logout и не создаёт параллельных конкурирующих клиентов одного контекста. Возврат в foreground инициирует проверку/восстановление.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NET-009", "source": "specs/tz_clear.md", "text": "Смена сети, sleep/wake, закрытие вкладки и потеря credentials обрабатываются без повреждения локального состояния. Возобновление stream не должно повторно создавать bubbles уже известных сообщений.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NAV-001", "source": "specs/tz_clear.md", "text": "Основные разделы: Контакты, Звонки, Чаты, Настройки. Начальный раздел — Чаты. Compact/wide варианты заданы UI Kit.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NAV-002", "source": "specs/tz_clear.md", "text": "Поиск расположен над соответствующим списком. Поиск чатов — по имени/JID/аккаунту, контактов — по имени/JID, звонков — по собеседнику. Это фильтр списков; полнотекстовый поиск истории отдельно не обещается.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NAV-003", "source": "specs/tz_clear.md", "text": "Чаты сортируются pinned-first при наличии pinned-функции, затем по последней активности, затем по имени для стабильности. Изменение unread не должно произвольно менять порядок при одинаковой активности.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NAV-004", "source": "specs/tz_clear.md", "text": "В списке видны avatar, имя, preview, время, unread и применимый status. Аккаунт отображается при необходимости различать одинаковые JID.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NAV-005", "source": "specs/tz_clear.md", "text": "Пустые данные и отсутствие совпадений поиска имеют разные объяснения. Создание чата/комнаты остаётся доступным в empty state.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NAV-006", "source": "specs/tz_clear.md", "text": "Back возвращает в предыдущий логический контекст. На широком экране смена selection не должна ломать sidebar; клавиатурная навигация обязательна для Web/Desktop.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CON-001", "source": "specs/tz_clear.md", "text": "Контакты синхронизируются через roster: initial state и последующие изменения. Удаление контакта из roster не удаляет историю.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CON-002", "source": "specs/tz_clear.md", "text": "Новый direct chat открывается по валидному JID с optional name и выбором добавления в roster. Отсутствие roster membership не запрещает сообщение само по себе.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CON-003", "source": "specs/tz_clear.md", "text": "Presence показывает реальное известное состояние; нет объявления online только из-за cached avatar/history.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CON-004", "source": "specs/tz_clear.md", "text": "MUC-комнаты показываются отдельно от людей. Список сохранённых комнат не выдаётся за полный серверный список членства.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CON-005", "source": "specs/tz_clear.md", "text": "Аватары публикуются/получаются через совместимые XMPP PEP mechanisms; legacy fallback допустим. Новый avatar нормализуется до разумного размера, baseline 512 px по длинной стороне.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CON-006", "source": "specs/tz_clear.md", "text": "При отсутствии изображения используется стабильный цвет и инициалы, для группы — group symbol. Обновление cache не требует перезапуска клиента.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CON-007", "source": "specs/tz_clear.md", "text": "Пользователю не обещается OMEMO для аватаров; доступ определяется серверными правами.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MSG-001", "source": "specs/tz_clear.md", "text": "Пустое после trim сообщение не отправляется. Каждая новая отправка имеет устойчивый уникальный client/origin id и зафиксированный аккаунт/получателя.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MSG-002", "source": "specs/tz_clear.md", "text": "До сетевого результата создаётся optimistic запись sending. Success transport send → sent, receipt → delivered, displayed → read. Ошибка → failed с объяснением.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MSG-003", "source": "specs/tz_clear.md", "text": "Sent означает передачу по клиентскому протокольному пути, delivered — полученный receipt, read — подтверждённый marker. UI не выводит read только из времени или online собеседника.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MSG-004", "source": "specs/tz_clear.md", "text": "Объединение live, Carbons и MAM не создаёт duplicate. Проверяются контекст аккаунта/чата и origin/stanza/client identities; archive UID не используется глобально для разных архивов.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MSG-005", "source": "specs/tz_clear.md", "text": "Доставка повышается монотонно sending → sent → delivered → read. Failed не «исправляется» молча архивной копией; явная повторная отправка — отдельное действие с контролем дубликатов.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MSG-006", "source": "specs/tz_clear.md", "text": "Порядок ленты — timestamp и устойчивый id при равных датах. Архивная вставка сверху сохраняет viewport.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MSG-007", "source": "specs/tz_clear.md", "text": "Служебные receipts, reactions, markers и пустые protocol messages не становятся обычными bubbles. Реальная ошибка дешифрования отображается как отдельное безопасное состояние.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MSG-008", "source": "specs/tz_clear.md", "text": "Чат с собой поддерживает текст/медиа и sync. Успешное собственное сообщение допускается помечать read по определённому self-chat правилу.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MSG-009", "source": "specs/tz_clear.md", "text": "У исходящего failed text доступно явное «Повторить», если payload сохранён. Повтор не должен незаметно менять encryption policy уже подготовленного сообщения; изменение режима требует нового явного решения.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "READ-001", "source": "specs/tz_clear.md", "text": "Новое входящее увеличивает локальный unread, если чат не просматривается активно. Архивный replay не раздувает счётчик повторно.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "READ-002", "source": "specs/tz_clear.md", "text": "При активном просмотре last-visible/latest incoming direct message отправляется displayed по протоколу; одно и то же состояние не рассылается без необходимости.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "READ-003", "source": "specs/tz_clear.md", "text": "Outgoing direct messages помечаются markable. Для MUC приложение не рассылает direct displayed markers в комнату как универсальный механизм прочтения всеми участниками.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "READ-004", "source": "specs/tz_clear.md", "text": "Поддерживается own-device sync read state через совместимое служебное расширение. Маркер, пришедший раньше сообщения, применяется после получения target. Пользователь не видит служебную запись в self-chat.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "READ-005", "source": "specs/tz_clear.md", "text": "Read marker — metadata; нельзя заявлять его E2EE только по encrypted body исходного сообщения.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "EDIT-001", "source": "specs/tz_clear.md", "text": "Используется совместимая message correction. Оригинал сохраняет свою идентичность и положение; заменяется body, устанавливается editedAt.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "EDIT-002", "source": "specs/tz_clear.md", "text": "Применение проверяет чат, автора, допустимый тип, security context и timestamp. Сторонний отправитель не может исправить чужое сообщение.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "EDIT-003", "source": "specs/tz_clear.md", "text": "Correction до оригинала удерживается в ограниченной pending очереди. Более старая correction не заменяет новую.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "EDIT-004", "source": "specs/tz_clear.md", "text": "Шифрование исправления соответствует исходному сообщению; не допускается plaintext раскрытие исправляемого encrypted body из-за текущего глобального переключателя.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REPLY-001", "source": "specs/tz_clear.md", "text": "Поддерживаются стандартная reply reference и fallback для совместимых старых клиентов. Unicode offsets считаются согласно протоколу, без смешения байтов и символов.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REPLY-002", "source": "specs/tz_clear.md", "text": "Отображается компактный preview источника, а fallback quote не дублируется в основном body.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REPLY-003", "source": "specs/tz_clear.md", "text": "Нажатие открывает источник/ветку, если reference известен. При недоступном оригинале показывается preview и объяснение без crash.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REPLY-004", "source": "specs/tz_clear.md", "text": "Legacy `>` quote допускается отображать без ложного target id. MUC replies ссылаются на room-assigned stanza id и корректный occupant identity.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REPLY-005", "source": "specs/tz_clear.md", "text": "Reference нельзя применить к другому чату с совпавшим id. Визуальная ветка — группировка reply, не отдельная серверная комната.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FWD-001", "source": "specs/tz_clear.md", "text": "Можно выбрать одно/несколько сообщений и переслать в существующий чат либо на валидный JID. Порядок: timestamp, устойчивый id.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FWD-002", "source": "specs/tz_clear.md", "text": "Создаются новые сообщения с новой identity и понятной атрибуцией. Пересылка не подделывает исходного sender.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FWD-003", "source": "specs/tz_clear.md", "text": "Media скачивается/расшифровывается и заново загружается для нового recipient и его encryption policy. Старый encrypted URI/key не переиспользуется автоматически.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FWD-004", "source": "specs/tz_clear.md", "text": "При частичной ошибке показывается количество успешно пересланного; уже доставленные элементы не откатываются и не повторяются молча.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "DEL-001", "source": "specs/tz_clear.md", "text": "«Удалить у меня» удаляет local row и сохраняет suppression всех известных identities, чтобы MAM/live echo не восстановили удалённое сообщение.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "DEL-002", "source": "specs/tz_clear.md", "text": "«Удалить у всех» отправляет retraction, проверяет авторство при применении и заменяет target на tombstone. Очищаются body/media/reply/reaction sensitive payload и связанные доступные cache.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "DEL-003", "source": "specs/tz_clear.md", "text": "Retract до оригинала удерживается pending. Generic fallback не повторяет удаляемое содержимое.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "DEL-004", "source": "specs/tz_clear.md", "text": "UI явно сообщает разницу локального удаления и отзыва. Ни одно не обещает стирание screenshots, backups, чужих exports или неподдерживающего клиента.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "DEL-005", "source": "specs/tz_clear.md", "text": "Массовое действие фильтрует/объясняет недоступные элементы; подтверждение показывает область действия и число сообщений.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REACT-001", "source": "specs/tz_clear.md", "text": "Реакции совместимы с XMPP reactions: target id и полный актуальный набор автора; пустой набор снимает реакцию.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REACT-002", "source": "specs/tz_clear.md", "text": "Emoji валидируются, дубликаты удаляются. Один reaction value — один grapheme, ограниченный безопасной длиной; baseline до 64 UTF-8 bytes.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REACT-003", "source": "specs/tz_clear.md", "text": "Показываются emoji, count и own state. Повторный tap переключает свой вклад. Более старое событие не отменяет новое.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REACT-004", "source": "specs/tz_clear.md", "text": "Direct авторы сравниваются по подготовленному bare JID, group — по корректной occupant identity. Нельзя объединять разных участников из-за неверной нормализации resource.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REACT-005", "source": "specs/tz_clear.md", "text": "Реакции не шифруются автоматически только из-за OMEMO текста. Базовая совместимая stanza является видимой серверу metadata; отдельное encrypted extension требует самостоятельного согласования и interoperability tests.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "TYPE-001", "source": "specs/tz_clear.md", "text": "Typing имеет active/composing/paused/inactive/gone. Baseline пауза после 5 с, удалённый composing истекает через 8 с без обновления.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "TYPE-002", "source": "specs/tz_clear.md", "text": "Настройка typing per-account; выключение прекращает отправку/отображение и очищает pending indicators. Для direct учитывается поддержка peer.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "TYPE-003", "source": "specs/tz_clear.md", "text": "В группе показываются имена для одного/двух участников, затем обобщённый статус. Переход между чатами/уход из foreground не оставляет вечное «печатает».", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MUC-001", "source": "specs/tz_clear.md", "text": "Пользователь создаёт/открывает room JID, задаёт nickname и optional name; для защищённых комнат предусмотрен запрос password при требовании сервера.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MUC-002", "source": "specs/tz_clear.md", "text": "Поддерживаются invitations, accept/join, occupant count, autojoin и информация о комнате. Invitees валидируются; некорректные адреса явно обозначаются.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MUC-003", "source": "specs/tz_clear.md", "text": "Новая encrypted-friendly комната конфигурируется persistent, members-only, nonanonymous и с доступными участникам affiliation lists, если сервер даёт эти права.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MUC-004", "source": "specs/tz_clear.md", "text": "Для encrypted send проверяются real JID всех необходимых online/offline recipients через occupants и member/admin/owner lists. Недоступный/неполный набор получателей блокирует безопасную отправку.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MUC-005", "source": "specs/tz_clear.md", "text": "Скрытые JID, отсутствие устройств или невозможность построить session не вызывают fallback к plaintext. Ошибка объясняет, что может изменить владелец/участник.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MUC-006", "source": "specs/tz_clear.md", "text": "Own echo дополняет room stanza identity даже при повторном encrypted payload. Replies/reactions становятся доступны после устойчивой серверной identity.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MUC-007", "source": "specs/tz_clear.md", "text": "«Выйти» сохраняет локальный чат/историю и снимает joined. «Удалить чат» удаляет локальную историю/сохранённую комнату после выхода; это не уничтожение комнаты сервера.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MUC-008", "source": "specs/tz_clear.md", "text": "После локального удаления поздние события текущей room session не создают чат заново без явного основания. Повторное приглашение/вход имеют определённую семантику.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ENC-001", "source": "specs/tz_clear.md", "text": "OMEMO включён по умолчанию для аккаунта. Per-chat override: наследовать / включено / выключено. UI показывает итоговый режим до отправки.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ENC-002", "source": "specs/tz_clear.md", "text": "Ошибка encryption никогда не приводит к автоматической plaintext отправке. Plaintext возможен только при явно выбранной политике.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ENC-003", "source": "specs/tz_clear.md", "text": "Поддерживаются legacy OMEMO и OMEMO 2 с совместимыми wire formats, device lists/bundles и согласованной lifecycle политикой identity/session.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ENC-004", "source": "specs/tz_clear.md", "text": "Для direct предпочтителен OMEMO 2 при готовности и поддержке peer; иначе совместимый legacy. Для group OMEMO 2 используется только при поддержке всех recipients; legacy остаётся encrypted fallback.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ENC-005", "source": "specs/tz_clear.md", "text": "Encrypt-to-self охватывает собственные другие устройства, чтобы Carbons/MAM могли быть прочитаны. Active own device не включается как чужой recipient с некорректной обязательной self-session.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ENC-006", "source": "specs/tz_clear.md", "text": "Private identity, prekeys и sessions сохраняются устойчиво и раздельно по аккаунтам. Обновление приложения не создаёт новую identity без необходимости.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ENC-007", "source": "specs/tz_clear.md", "text": "TOFU и verified различаются. Первое доверие отмечается как автоматическое; changed identity переводится в undecided и требует понятного решения. Compromised key не используется как trusted.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ENC-008", "source": "specs/tz_clear.md", "text": "Пользователь видит список устройств, protocol support, fingerprint, active state и trust, может отметить проверенный fingerprint и снять verification.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ENC-009", "source": "specs/tz_clear.md", "text": "OMEMO encryption/decryption выполняются в клиентском endpoint. Web gateway может передавать encrypted stanza, но не получает password/crypto state для скрытой серверной расшифровки. Применяются проверенные криптографические реализации и совместимые test vectors. Собственный новый алгоритм, замена примитивов или трактовка общего session storage как доказанной interoperability не допускаются.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ENC-010", "source": "specs/tz_clear.md", "text": "Зашифрованный text не означает шифрование JID, времени, stanza ids, replies metadata, reactions, typing, avatars или custom sync. Матрица раскрываемых metadata является частью security документации каждого релиза.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "ENC-011", "source": "specs/tz_clear.md", "text": "Криптографический формат OMEMO 2 реализуется по утверждённой совместимой редакции с SCE и необходимыми payload/key/MAC rules; он не заменяется media AES-GCM только из-за удобства библиотеки.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FILE-001", "source": "specs/tz_clear.md", "text": "Поддерживаются файл, фото, видео, музыка, voice и videoNote. Тип определяется безопасно по metadata/MIME/доступному анализу; расширение не даёт права автоматически выполнять содержимое.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FILE-002", "source": "specs/tz_clear.md", "text": "Можно выбрать до 20 элементов за пакет, просмотреть, удалить отдельные и добавить общую подпись. Перевышение лимита объясняется; элементы не теряются молча.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FILE-003", "source": "specs/tz_clear.md", "text": "Источник копируется/удерживается в staged draft с достаточным сроком доступа. Не предполагается, что временный URL picker остаётся доступным после его закрытия.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FILE-004", "source": "specs/tz_clear.md", "text": "При encrypted policy blob шифруется до upload случайным file key; ключ передаётся внутри защищённого сообщения, не upload service. Для plaintext это явно обозначено.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FILE-005", "source": "specs/tz_clear.md", "text": "Используется HTTP File Upload discovery/slot. Выбирается подходящий component по реально загружаемому размеру. Ограничение сервера и памяти отображается до бессмысленного повторения операции.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FILE-006", "source": "specs/tz_clear.md", "text": "Upload/download допускаются по HTTPS. Проверка распространяется на redirect chain; переход к небезопасной схеме не допускается. HTTP headers/credentials slot не отправляются произвольному другому origin после redirect.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FILE-007", "source": "specs/tz_clear.md", "text": "Сохраняется исходное безопасное расширение filename. Encrypted media URI использует совместимую aesgcm scheme/key fragment, а не вымышленное обязательное расширение файла.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FILE-008", "source": "specs/tz_clear.md", "text": "Body media-сообщения остаётся распознаваемой ссылкой; plaintext дополнительно передаёт совместимый OOB. Подпись пакета — отдельный text/reply к первому подходящему вложению.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FILE-009", "source": "specs/tz_clear.md", "text": "Пакет отправляется с контролем порядка. Successful drafts удаляются из pending, failed остаются для retry; caption отправляется после успешных вложений. Ошибка caption не откатывает уже отправленные файлы.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FILE-010", "source": "specs/tz_clear.md", "text": "Retry сохраняет account/recipient/message identity и encryption context. Сбой после PUT, но до XMPP send может оставить orphan blob; это не обозначается как гарантированно удалённый файл.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FILE-011", "source": "specs/tz_clear.md", "text": "Загрузки поддерживают progress по доступным данным, cancellation и bounded retry. Недостаток диска/памяти обрабатывается как ошибка без повреждения остальных сообщений.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "FILE-012", "source": "specs/tz_clear.md", "text": "В Web endpoint обязан поддерживать необходимые browser access/CORS политики. Proxy не получает file key или decrypted blob для обхода ограничений незаметно для пользователя.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MEDIA-001", "source": "specs/tz_clear.md", "text": "Photo/video имеют inline preview с сохранением aspect ratio без неожиданного crop. Loading/error/placeholder различаются.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MEDIA-002", "source": "specs/tz_clear.md", "text": "Фото открывается в viewer с zoom/pan. Видео имеет play/pause/seek/fullscreen и доступные системные controls. Voice/audio — inline player, duration, seek, progress; voice speeds 1×/1.5×/2×.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MEDIA-003", "source": "specs/tz_clear.md", "text": "В пределах приложения активный media playback согласован: начало другого audio/video не создаёт неконтролируемое одновременное звучание. Системный audio focus обрабатывается по платформе.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MEDIA-004", "source": "specs/tz_clear.md", "text": "VideoNote показан кругом, воспроизводится inline и увеличивается при playback. Изменение размера не вызывает потерю позиции чтения.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MEDIA-005", "source": "specs/tz_clear.md", "text": "Preview cache не скачивает один файл многократно из-за повторного появления row. Decrypted cache ограничивается размером/сроком и очищается согласно privacy/account lifecycle.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MEDIA-006", "source": "specs/tz_clear.md", "text": "Экспорт/скачивание/копирование выполняются явно. Пользователь выбирает доступное платформенное место сохранения; отмена не показывает success.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MEDIA-007", "source": "specs/tz_clear.md", "text": "Viewer закрывается доступной кнопкой/keyboard action и gesture по UI Kit. Zoomed pan не конфликтует с dismiss.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "MEDIA-008", "source": "specs/tz_clear.md", "text": "Неподдерживаемый codec/file открывается безопасным fallback/download с объяснением; не имитируется успешное воспроизведение.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REC-001", "source": "specs/tz_clear.md", "text": "Разрешения microphone/camera запрашиваются по действию пользователя. Отказ не ломает текстовый composer.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REC-002", "source": "specs/tz_clear.md", "text": "Voice: start, elapsed, cancel, finish; запись короче 0.4 с не отправляется. Длительность голоса не ограничивается автоматически 60 секундами: ограничения файла/сервера действуют отдельно.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REC-003", "source": "specs/tz_clear.md", "text": "VideoNote: до 60 с, корректная ориентация, переключение камеры при доступном hardware. Минимальный валидный media asset — 0.8 с; early stop может дождаться достаточного capture, baseline 1.2 с.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REC-004", "source": "specs/tz_clear.md", "text": "Отпускание/отмена до асинхронного старта capture не оставляет скрытую запись. Finalization имеет timeout и завершает UI в определённое состояние.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REC-005", "source": "specs/tz_clear.md", "text": "При interruption пригодный partial asset может быть предложен для восстановления/предпросмотра, но не отправляется автоматически как подтверждённое действие.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "REC-006", "source": "specs/tz_clear.md", "text": "На touch поддерживаются hold/slide cancel/lock. На mouse/keyboard всегда есть явные start/stop/cancel; жест не является единственным способом записи.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "GEO-001", "source": "specs/tz_clear.md", "text": "Отправка текущей или выбранной точки доступна через меню вложения. Разрешение location запрашивается только в этом сценарии.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "GEO-002", "source": "specs/tz_clear.md", "text": "При denied/отсутствии GPS доступен ручной выбор координат на карте либо ввод точки. Live tracking в scope не входит.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "GEO-003", "source": "specs/tz_clear.md", "text": "Передаётся совместимый geo URI: finite latitude −90…90, longitude −180…180, optional nonnegative uncertainty. UI не выдаёт число знаков после запятой за точность датчика.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "GEO-004", "source": "specs/tz_clear.md", "text": "Карта/tiles provider и передача ему coordinates отражены в privacy конфигурации решения. OMEMO чата не скрывает запрос карты от её провайдера.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "HIST-001", "source": "specs/tz_clear.md", "text": "История хранится локально с изоляцией аккаунтов. Существующие сообщения доступны при временном отсутствии сети, если устройство/профиль допускает persistent storage.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "HIST-002", "source": "specs/tz_clear.md", "text": "На первом входе загружается ограниченное недавнее окно, baseline 40 сообщений. Полная многолетняя история не блокирует запуск; старое догружается по запросу/прокрутке.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "HIST-003", "source": "specs/tz_clear.md", "text": "Account archive и каждая MUC имеют собственные checkpoint. Cursor непрозрачен, не вычисляется из local id и не переносится между архивами.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "HIST-004", "source": "specs/tz_clear.md", "text": "Incremental запрос использует stored cursor. При его истечении допустим однократный timestamp fallback с overlap 60 с. Цикл cursor↔timestamp запрещён.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "HIST-005", "source": "specs/tz_clear.md", "text": "Проверяются query id, допустимый источник, порядок завершения и размер страницы. Чужой результат/overflow не считается успешной историей.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "HIST-006", "source": "specs/tz_clear.md", "text": "Missing/repeating cursor у incomplete page прекращает проход с recoverable error. Не допускаются вечный spinner и пропуск остатка как якобы complete.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "HIST-007", "source": "specs/tz_clear.md", "text": "Архивные mutations применяются согласованными пачками. Durable checkpoint продвигается только после успешной локальной транзакции соответствующих данных. Ошибка диска сохраняет предыдущую точку восстановления.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "HIST-008", "source": "specs/tz_clear.md", "text": "Backward pagination берёт следующий before из server RSM first даже если страница содержала только reactions/retractions/дубликаты.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "HIST-009", "source": "specs/tz_clear.md", "text": "Pending correction/retraction/reaction/read marker применяются после target. Очереди ограничены и очищаются по политике; overflow не создаёт crash.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "HIST-010", "source": "specs/tz_clear.md", "text": "Расшифрование и большие batches уступают время UI. Background/media capture/upload могут временно снижать архивную активность; возобновление не теряет checkpoint.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "HIST-011", "source": "specs/tz_clear.md", "text": "Автоматические retries ограничены; после исчерпания показывается recoverable state и доступно повторить. Незавершённый проход не объявляется «История полностью загружена».", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "HIST-012", "source": "specs/tz_clear.md", "text": "Локальная миграция выполняется транзакционно; исходный формат удаляется после успешной записи. Upgrade не должен уничтожать единственную durable копию данных.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CALL-001", "source": "specs/tz_clear.md", "text": "Поддерживаются аудио-/видеозвонки один на один, один активный звонок на клиентский контекст. Второй входящий/исходящий получает определённый busy/reject сценарий.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CALL-002", "source": "specs/tz_clear.md", "text": "До запуска запрашиваются microphone/camera permissions. Есть incoming accept/decline, connecting, connected, elapsed и завершение.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CALL-003", "source": "specs/tz_clear.md", "text": "Доступны mute, camera enable/disable, switch camera при нескольких камерах и speaker/audio output выбор в пределах платформенных возможностей.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CALL-004", "source": "specs/tz_clear.md", "text": "Используется совместимый Jingle/JMI signaling и WebRTC media с ICE/DTLS-SRTP. Endpoint выбирается как подходящий full JID; последующие сообщения согласованы с тем же ресурсом.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CALL-005", "source": "specs/tz_clear.md", "text": "SDP media sections сохраняют порядок offer. ICE candidates удерживаются до готового remote description, затем передаются/применяются без вечного ожидания bare/full JID.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CALL-006", "source": "specs/tz_clear.md", "text": "STUN/TURN обнаруживаются через extdisco или утверждённую конфигурацию. Проверяются scheme, host/port, transport, expiration и credentials. Невалидная запись не приводит к crash медиадвижка.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CALL-007", "source": "specs/tz_clear.md", "text": "TURN relay необходим для утверждённой тестовой матрицы сложных сетей. Отсутствие relay показывается диагностически; STUN не описывается как гарантия соединения за любым NAT.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CALL-008", "source": "specs/tz_clear.md", "text": "Внешний fallback STUN допускается только как задокументированный конфигурационный выбор. Сервис-получатель сетевых адресов отражается в privacy документации.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CALL-009", "source": "specs/tz_clear.md", "text": "Смена сети/краткая ICE failure имеют ограниченное recovery окно. После него звонок завершается корректно, освобождает tracks/camera/microphone и снимает active state.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CALL-010", "source": "specs/tz_clear.md", "text": "Закрытие экрана звонка не может оставить скрыто включённый microphone/camera вопреки показанному состоянию. Background behavior задаётся интеграцией платформы, не визуальным состоянием окна.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CALL-011", "source": "specs/tz_clear.md", "text": "Каждый звонок создаёт одну history card: направление, media type, начало, duration и outcome.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CALL-012", "source": "specs/tz_clear.md", "text": "Missed incoming увеличивает unread. Дубликаты completion callbacks не создают несколько карточек.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "CALL-013", "source": "specs/tz_clear.md", "text": "Call history синхронизируется с собственными устройствами через совместимое расширение и MAM/Carbons, если сервер хранит такие события. Metadata не выдаётся за OMEMO body.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "PUSH-001", "source": "specs/tz_clear.md", "text": "Поддерживаются локальные уведомления для новых событий активного клиента и отдельная push-интеграция для разрешённых платформенных состояний.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "PUSH-002", "source": "specs/tz_clear.md", "text": "Notification создаётся для нового incoming, не для outgoing/повторного MAM. В активно просматриваемом чате дублирующий banner подавляется.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "PUSH-003", "source": "specs/tz_clear.md", "text": "Уведомление содержит безопасную идентичность account/conversation/event для перехода в правильный контекст. Повторная доставка push и network event дедуплицируется.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "PUSH-004", "source": "specs/tz_clear.md", "text": "Default privacy: push payload не содержит plaintext body, file key или credentials. Preview после получения сообщения определяется пользовательской настройкой; при app lock default preview скрыт.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "PUSH-005", "source": "specs/tz_clear.md", "text": "Gateway/registration lifecycle включает register/update token, enable по XMPP, disable/logout/revoke и обработку expired token. Наличие server push feature без registration не отображается как «Push работает».", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "PUSH-006", "source": "specs/tz_clear.md", "text": "Push — сигнал получения/пробуждения, а не источник истины истории. После него клиент синхронизируется с сервером; утерянный push не должен навсегда потерять сообщение.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "PUSH-007", "source": "specs/tz_clear.md", "text": "Базовый single-active-account режим регистрирует доставку для активного аккаунта; переключение согласует старую и новую registration. Уведомления неактивных аккаунтов не обещаются без отдельно реализованного multiaccount background режима. Поздний push сохраняет исходную account identity и не открывает переписку другого аккаунта.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "WEB-001", "source": "specs/tz_clear.md", "text": "Для уведомлений вне открытой страницы поставляется поддержанный Web Push/service worker путь и gateway, если браузер/пользователь предоставили возможность. При отсутствии поддержки/permission приложение честно показывает статус «Только при открытом приложении».", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "WEB-002", "source": "specs/tz_clear.md", "text": "Закрытая страница не считается постоянно подключённой XMPP-сессией. Service worker notification не гарантирует непрерывный microphone, медиазвонок или автоматический показ полноэкранного incoming UI.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "WEB-003", "source": "specs/tz_clear.md", "text": "Incoming push может уведомить о вызове и открыть приложение по действию. После открытия проверяются актуальность и состояние вызова; истёкший вызов не «принимается» из старого notification.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "WEB-004", "source": "specs/tz_clear.md", "text": "Несколько вкладок координируют активное соединение/device state либо используют изолированные ресурсы с безопасным доступом к crypto state. Не допускаются конкурентные повреждающие записи ratchet sessions.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "DESK-001", "source": "specs/tz_clear.md", "text": "Пользователь понимает разницу «закрыть окно», «скрыть/свернуть» и «выйти из приложения». Работа в tray/фоновой сессии и автозапуск — явно управляемые настройки.", "applicability": "out_of_scope", "reason": "Native Android/Desktop lifecycle; excluded from Web-only implementation." }, { "id": "DESK-002", "source": "specs/tz_clear.md", "text": "При живом фоновом процессе поддерживаются сообщения и incoming calls. Полностью завершённый процесс не получает обещание гарантированного пробуждения без отдельного системного механизма.", "applicability": "out_of_scope", "reason": "Native Android/Desktop lifecycle; excluded from Web-only implementation." }, { "id": "DESK-003", "source": "specs/tz_clear.md", "text": "Sleep/wake, network change и logout восстанавливают/отключают соединение и push registration корректно. Tray icon не показывает active call после завершения.", "applicability": "out_of_scope", "reason": "Native Android/Desktop lifecycle; excluded from Web-only implementation." }, { "id": "AND-001", "source": "specs/tz_clear.md", "text": "Поставляется интеграция системной доставки уведомлений и входящих вызовов для утверждённого режима устройства. Выбор push provider и доступность устройств без соответствующего сервиса фиксируются в паспорте релиза.", "applicability": "out_of_scope", "reason": "Native Android/Desktop lifecycle; excluded from Web-only implementation." }, { "id": "AND-002", "source": "specs/tz_clear.md", "text": "Фоновая работа соответствует lifecycle/permissions ОС. Постоянный socket в обычном скрытом UI не используется как единственная гарантия доставки.", "applicability": "out_of_scope", "reason": "Native Android/Desktop lifecycle; excluded from Web-only implementation." }, { "id": "AND-003", "source": "specs/tz_clear.md", "text": "Для ongoing call используется разрешённый системный foreground/call механизм с видимым статусом; control из notification согласован с app state.", "applicability": "out_of_scope", "reason": "Native Android/Desktop lifecycle; excluded from Web-only implementation." }, { "id": "AND-004", "source": "specs/tz_clear.md", "text": "Force stop, отозванные разрешения, ограничения батареи и отключённая сеть имеют задокументированную деградацию. Приложение не обещает обход пользовательского запрета ОС.", "applicability": "out_of_scope", "reason": "Native Android/Desktop lifecycle; excluded from Web-only implementation." }, { "id": "STORE-001", "source": "specs/tz_clear.md", "text": "История, crypto state и настройки раздельны по accountId; операции сохранения транзакционны либо имеют проверяемый equivalent recovery механизм.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "STORE-002", "source": "specs/tz_clear.md", "text": "Native credentials защищены системным secure storage; private key material защищается подходящим устройству key wrapping/access control. Пароль не хранится в открытом preferences файле.", "applicability": "out_of_scope", "reason": "Native secure storage; Web addressed by STORE-003/004." }, { "id": "STORE-003", "source": "specs/tz_clear.md", "text": "В Web пароль не хранится plaintext в localStorage, URLs, analytics или общедоступных configuration objects. Persistent login и разблокировка crypto state используют отдельное задокументированное защищённое решение; отсутствие такого решения означает повторный вход, а не незаметное ослабление.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "STORE-004", "source": "specs/tz_clear.md", "text": "Web storage может иметь квоты/очистку. Приложение обрабатывает quota/exhaustion и показывает, когда история не сохранена устойчиво. Browser storage не представляется эквивалентом hardware-backed native vault.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "STORE-005", "source": "specs/tz_clear.md", "text": "Media cache имеет лимит и eviction. Draft/failed payload не исчезает без объяснения; при невозможном retry действие отключено с причиной.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "STORE-006", "source": "specs/tz_clear.md", "text": "Автосохранение не теряет введённый текст при переходах/обычном восстановлении. Draft принадлежит account + conversation; он не переносится в другой чат из-за reuse UI.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "STORE-007", "source": "specs/tz_clear.md", "text": "Миграции versioned и тестируются на старых данных/сбоях. Ошибка открытия persistent store показывает ограниченный режим, а не ложное подтверждение durable записи.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "LOCK-001", "source": "specs/tz_clear.md", "text": "App lock скрывает всю sensitive UI: чат, media, call details и previews. Поддерживаются пользовательский passcode и доступная системная биометрия.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "LOCK-002", "source": "specs/tz_clear.md", "text": "Минимальная длина passcode 4 символа, предусмотрены ограничение частоты ошибочных попыток и корректное хранение verifier/секрета. App lock не объявляется шифрованием базы без отдельного encryption механизма.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "LOCK-003", "source": "specs/tz_clear.md", "text": "После запуска и ухода в background lock применяется по настройке. Краткая потеря focus для системного picker/permission dialog не прерывает незавершённую операцию.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "LOCK-004", "source": "specs/tz_clear.md", "text": "Web не обещает native biometric unlock на любом браузере; при отсутствии защищённой интеграции остаётся passcode либо повторная авторизация. Lock settings показывают фактическую возможность.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "SEC-001", "source": "specs/tz_clear.md", "text": "Документируется разделение transport TLS, OMEMO payload, file encryption, DTLS-SRTP media, local protection и UI lock. Термины не подменяют друг друга.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "SEC-002", "source": "specs/tz_clear.md", "text": "Server/upload/STUN/TURN/maps/push providers получают только необходимые данные. Перечень providers и metadata доступен пользователю.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "SEC-003", "source": "specs/tz_clear.md", "text": "Логи исключают passwords, tokens, private/session keys, decrypted bodies и file key fragments. Сетевые трассы по умолчанию обезличены; диагностический экспорт требует явного действия и предупреждения о metadata.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "SEC-004", "source": "specs/tz_clear.md", "text": "Полученные text/filenames/URLs/XML не выполняются как HTML/script/команда. Web rendering безопасен для XSS; переход по внешним URL не передаёт секретный контекст.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "SEC-005", "source": "specs/tz_clear.md", "text": "У ограничений входных данных есть предельный размер/depth/count. Недоверенные stanza, challenges, media metadata и custom sync parsers не должны создавать бесконечную работу/выделение памяти.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "SEC-006", "source": "specs/tz_clear.md", "text": "Copy/export явно выводит plaintext за границы клиента; локальная очистка не обещает удалить clipboard или пользовательский файл.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "SEC-007", "source": "specs/tz_clear.md", "text": "«Удалить у всех» — протокольный отзыв; «Удалить локальные данные» — удаление собственного профиля. В UI нет обещания абсолютного стирания всех копий.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "SEC-008", "source": "specs/tz_clear.md", "text": "Для push/служебной own-device синхронизации проверяется источник и принадлежность аккаунту. Remote peer не может подделать собственную call/read history только прислав похожий XML element.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NFR-001", "source": "specs/tz_clear.md", "text": "UI Kit является обязательным стандартом visual/interaction behavior. Small/wide layout определяется доступной шириной, не строкой User-Agent.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NFR-002", "source": "specs/tz_clear.md", "text": "Списки/лента виртуализируются или используют equivalent bounded rendering. Большой архив не создаёт все визуальные rows одновременно.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NFR-003", "source": "specs/tz_clear.md", "text": "Проект задаёт измеряемые бюджеты startup, RAM, cache и frame responsiveness для утверждённых reference devices. До утверждения devices не заявляется произвольный универсальный SLA.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NFR-004", "source": "specs/tz_clear.md", "text": "Encryption/decoding/uploads уступают ресурсы active input/capture. Scroll и text entry остаются доступными во время catch-up.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NFR-005", "source": "specs/tz_clear.md", "text": "Системные permissions запрашиваются по контексту. Denied, hardware missing и revoked during session входят в тестовую матрицу.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NFR-006", "source": "specs/tz_clear.md", "text": "Web/Desktop полностью управляются клавиатурой; Android поддерживает системную accessibility. Focus, text scale, reduced motion и contrast проверяются по UI Kit.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NFR-007", "source": "specs/tz_clear.md", "text": "Сборки воспроизводимы: pinned/locked dependencies, migrations, build instructions, CI, license notices и release artifacts. Выбор framework не включён в пользовательские требования.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NFR-008", "source": "specs/tz_clear.md", "text": "CI запускает unit/integration checks и smoke UI tests для поставляемых targets. Подпись/публикация и secrets отделены от публичного репозитория.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "NFR-009", "source": "specs/tz_clear.md", "text": "Crash/error reports не включают sensitive content по умолчанию. Телеметрия имеет утверждённую privacy-конфигурацию.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-001", "source": "specs/uikit_clear.md", "text": "Контент и общение находятся на первом плане. Декор не конкурирует с текстом, avatar и основным действием.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-002", "source": "specs/uikit_clear.md", "text": "Основной accent — синий. Outgoing сообщения синие, incoming нейтральные. Направление различается также выравниванием, а состояние — иконкой/подписью.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-003", "source": "specs/uikit_clear.md", "text": "Элементы округлые, поверхности спокойные, navigation и forms следуют привычкам платформы. Нет обязательного копирования внешнего вида одной ОС на другую.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-004", "source": "specs/uikit_clear.md", "text": "Полупрозрачность поддерживает иерархию, но не ухудшает чтение. При отсутствии blur/пониженной прозрачности используется определённый opaque fallback.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-005", "source": "specs/uikit_clear.md", "text": "Состояния loading/empty/error/disabled/selected являются частью компонента, а не отдельной импровизацией каждого экрана.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-006", "source": "specs/uikit_clear.md", "text": "Жест ускоряет действие, но для значимого действия есть видимый/доступный альтернативный control.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-007", "source": "specs/uikit_clear.md", "text": "Пользовательские строки — русские, короткие и точные. «Отправлено», «Доставлено» и «Прочитано» не заменяют друг друга.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-008", "source": "specs/uikit_clear.md", "text": "Маленькое окно, клавиатура, увеличение текста и reduced motion поддерживаются системно, а не исправляются после завершения дизайна.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-AVATAR", "source": "specs/uikit_clear.md", "text": "Circle, photo fill с crop, fallback — initials/group icon и стабильный фон. Не смешивать photo fit с avatar fill: фотографии сообщений не обрезаются как avatar.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-MESSAGE", "source": "specs/uikit_clear.md", "text": "Incoming слева, outgoing справа. Outer horizontal inset 12, row gap 8. Opposite minimum space 54 для текста и 16 для media, с уменьшением в узком viewport. Body wrapping не расширяет страницу горизонтально.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-A11Y-001", "source": "specs/uikit_clear.md", "text": "Целевой контраст обычного текста минимум 4.5:1, крупного 3:1; значимых controls/focus минимум 3:1 относительно соседних поверхностей. Проверяются фактические composite colors, не только исходные HEX.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-A11Y-002", "source": "specs/uikit_clear.md", "text": "Все действия доступны screen reader и имеют names/states. Icon-only button не называется именем файла icon.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-A11Y-003", "source": "specs/uikit_clear.md", "text": "Web/Desktop полностью поддерживают Tab/Shift+Tab, Enter/Space для действий, Escape для закрытия и предсказуемый focus order. Hover-only actions доступны также по focus/tap.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-A11Y-004", "source": "specs/uikit_clear.md", "text": "При text scale/zoom до 200% интерфейс reflow без потери основных действий. Fingerprint/URI можно прочитать полностью; text body не скрывается за fixed height.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-A11Y-005", "source": "specs/uikit_clear.md", "text": "Touch targets минимум 48×48 u для действий; визуально меньшая icon сохраняет просторный hit region. На pointer target не меньше 44×44 для основных icon actions.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-A11Y-006", "source": "specs/uikit_clear.md", "text": "Errors связаны с input, loading не бесконечно повторяется screen reader, live messages объявляются умеренно и не перехватывают focus.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-A11Y-007", "source": "specs/uikit_clear.md", "text": "Reduced motion/transparency и high contrast имеют определённые варианты. Цвет не единственный способ различения unread/failed/verified.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." }, { "id": "UI-A11Y-008", "source": "specs/uikit_clear.md", "text": "Record/call/media controls отражают фактическую активность camera/microphone. Для destructive есть явное подтверждение области действия.", "applicability": "web", "reason": "Web requirement; cross-platform clauses apply only in Web context." } ]