🛡️ «Шаблон»/«Заменить БД» чужого бэкапа на пире команды — отдельный вопрос, главная кнопка «Отмена» (вариант B владельца)
🔄 Роль читается в момент показа диалога, неизвестная — как пир; тексты про перезапись и «только локально» исправлены
Исправления
Сброс пароля и сосед при лимите и пустом ответе объясняют причину
🛠️ Общий `httpFailureText` для экранов мимо репозитория: пустое тело и `"error":""` → запасной текст, 429 → «подождите», HTML прокси и длинное тело не показываются
Регистрация при лимите и пустом ответе объясняет причину
💬 Пустое «Ошибка: » заменено строкой «Слишком много попыток… подождите несколько минут» (ru/en)
«Всё равно оформи» в голосе не теряет контекст
💬 Короткий ответ с «всё равно/всё-таки» — уточнение с историей
«Речь не найдена» словами при пустом ответе узла
💬 (Часть: текст отказа; след на строке — остаток)
Team Sync снова видит свою команду (, владелец)
🧠 Своя команда — по своему id или по владельцу; строка лечится heartbeat-ом, в т.ч. после импорта снимка
🧼 «Принять без настройки» убрана по решению владельца
«Номер снят с продажи» в ИИ-чате звучит вопросом
💬 Room_inactive: причина и варианты вместо «Повторите запрос»
Отказ виден внутри окна формы и диалога выбора
🪟 (Возврат ретеста №368)
«Сосед #N» в расчётах на языке приложения
🌍 Data-слой больше не подставляет русскую заглушку имени, экраны берут ресурс
Локализованный текст больше не замерзает на старте процесса
🌍 Поколение локали LanguageManager.localeEpoch сбрасывает кэши локализованного текста (Application, индекс поиска настроек)
🔗 (Фикс №364 охота, мерж по решению владельца — №367 разбор)
Шторка загрузки: фаза словами, честная скорость, «Отменить»
«О приложении»: перенос строк, честная «Проверить снова», живая карточка обновлений
Отчёт импорта говорит правду о потерях
📋 Итог предпросмотра (снесено/откатано) и строка о командной сверке в отчёте после импорта
Восстановленный пир ждёт базовую станцию
🛡️ После своего restore не-БС пир 10 мин не пушит всю базу на hash_mismatch(BASE_STATION) и не копит серию convergence-guard
Отказ фичи виден человеку, а не только журналу
🚨 Девять мест во ViewModel, где спиннер гас молча, теперь говорят отказ оверлеем на языке приложения
🧾 Журнал не тронут: английская трасса цены и записи моделей провайдера на месте
🧷 Семь законных фоновых мест объявлены маркером в коде, планка класса _tools/kt-refusal-swallowed-check.py: 16 → 0
Лимит частоты больше не разлогинивает ()
🚨 429/408 на refresh → Failed.Network: сессия и данные объекта целы
版本 1.2610.4343
Новое
«Быстрая продажа» в меню карточки гостя
Исправления
Отказ use case показывается текстом языка приложения
Непарная скобка в регэкспе больше не роняет ИИ-чат ()
🚨 `CustomApiDefaults`: `\}\}` вместо голой `}}` — ICU на аппарате больше не бросает PatternSyntaxException в <clinit>, Custom-провайдер и чат на профиле узла живы
💬 Краш уже в prod (19c9164f4) — релиз за владельцем
Журнал не подставляет русский e.message своих исключений
Плеер объясняет отказ, лечилка путей фото, список исчезающих строк
🔊🩹🔍 Остатки зоны бэкапов (,)
Одна точка в откате, честная пятёрка устройств
✏️ «Неполный откат» склеивается без двойной точки
📊 Отчёт ФЗ-374 берёт пять устройств по трафику, затем времени и MAC
💬 Сдача фоновой смены №298, влита живой сессией
После сброса нет второго главного
🛡️ Авто-создание команды не делает аппарат вторым главным, если своё главное видно в discovery (сырой id и mDNS-хеш)
📢 Отказ виден баннером экрана; развилка B/C ждёт владельца в
💬 Сдача фоновой смены №297, влита живой сессией
Адрес роутера стирается, Custom шлёт тело
🧹 Сохранённый адрес роутера можно стереть: «Сохранить» активна по несохранённым изменениям, мониторинг отвязывается
📨 Пресет Custom без шаблона шлёт OpenAI-совместимое тело с экранированным промптом
💬 Сдача фоновой смены №295, влита живой сессией
«Включить ИИ» выдаёт согласия и на голос
🎙️ Включение встроенного ИИ выдаёт все три облачных согласия (LLM, ASR, TTS) одним списком
🔐 Гейт диалога требует все три, а не только LLM
💬 Сдача фоновой смены №289, влита живой сессией
Перетаскивание кнопки-столбика долгим тапом
🛠️ Fix/fab-drag-stale-offset: жест больше не замыкает устаревшее смещение
📒 Backup.log всегда, с ротацией и без ПДн; «Поделиться журналом операций» на «Обслуживание БД» ()
Исправления
Импорт бэкапа из другой сборки переносит пути медиа в свой filesDir
🎧 Записи звонков и фото номеров из архива беты живые в релизе ()
🩹 Уже импортированные записи лечатся сами при старте и раз в 6 ч
Сброс Team Account выходит из команды на сервере
🚪 «Сбросить Team Account» сначала говорит серверу `leave-team`; нет связи — сброс не выполняется и об этом сказано
🛡️ Запоздавший ответ heartbeat'а не воскрешает команду, членство и роль БС (гейт по ключу команды)
🔁 Выбор роли возвращает в команду (`rejoin-team`) и пишет ключ — синк поднимается без перелогина
版本 1.2609.4212
Новое
Мастер ИИ без дорогой модели
Свои Wi-Fi-учётки спутникам брони
🎉 При заселении каждый спутник брони получает персональную учётку Wi-Fi (решение владельца: всем спутникам при заселении)
🔐 Жизненный цикл как у основного гостя: продление, выезд, отмена; открепление от заселённой брони — отложенное снятие без блокировки повторной выдачи
🧠 Воркер роутера видит спутников в пяти запросах «активной брони»: учётка не сносится как «грант без срока», журнал ФЗ-374 и «Активные» знают номер спутника
📶 Диалог заселения со всеми парами логин/пароль (и с календаря), «Wi-Fi спутников» в карточке брони с SMS на телефон спутника
🏨 Монитор считает устройства спутников в номере; дельта booking_guests будит воркер БС
🎉 К брони прикрепляются гости-спутники: блок «Сопровождающие» внизу карточки гостя формы — поиск по имени и телефону, создание нового гостя с предзаполнением, «−» с «Отменить»
🔎 Бронь находится по любому своему гостю: список броней, глобальный поиск, профиль («Спутником: N»), календарь «Фамилия +N», чипы в карточке и диалоге брони
🗄️ Синкуемая таблица booking_guests (миграция 32→33, детерминированный uuid пары, 7 реестров синка, пустая таблица не рвёт отпечаток со старыми сборками)
🛡️ Форма брони больше не перечитывает бронь при возврате с другого экрана и не теряет спутников молча на «Назад»
🚧 Вне цикла: Wi-Fi-учётки спутникам (multi-guests-wifi), смена основного гостя, split-folio, ИИ-инструменты
Один платёж — несколько броней (вариант A) влит в ствол
🧱 Payments.receipt_group_uuid + миграция v31→v32: доли одного перевода делят общий ключ
🎉 Экран «Оплата за несколько броней» из меню гостя, из брони и из карточки предоплаты: по долгам, поровну, остаток — аванс гостя
🧾 Карточка платежа показывает гостя и состав поступления, аннулирует долю или всё поступление; правка платежа без брони больше не тупик
🤖 ИИ: register_payment с allocations и авторазнесением при точном совпадении с долгами, новый allocate_payment для уже записанной предоплаты
📊 Выручка, статистика и метрики считают поступление одной транзакцией; удалённые платежи больше не попадают в выручку и поиск ИИ
🛡️ Полный ci-check локально и на сервере зелёный: 11 217 тестов, 16 гардов; ревью кода, синка и регрессий закрыты
🧮 JournalEnglishTraceRatchetTest считает три рода дверей; TAG_FORM_RUSSIAN_MAX=6 — видимый долг, наряд взят №239
Номер брони в имени гостя отбивается до карточки
🎯 Guest_name из номера или кода брони — отказ с подсказкой про booking_id (платёж и скидка)
🤫 Молчим при известной брони, guest_id или guest_phone; ноль номером не считаем
🟢 Полный прогон 11460/0, семь зондов красные
Код брони доходит до инструмента
🎯 Строка-код в booking_id любого инструмента → число единственной брони (за барьерами реестра, до проверки аргументов)
🛡️ Неоднозначный или неизвестный код — отказ; номера парами «#id (код …)» для HumanBookingRefs
🟢 Полный прогон 11453/0, семь зондов красные
Отказ по Wi-Fi виден
Служба станции уходит с ролью
📡 Симптом 1 (№239 ремонт)
Сотрудник в задаче уборки
Пустые замеры сводки не нули
Ручная цена не выключает сборы
Один звонок, одна запись
Форма не подменяет взрослых
Выход доводится до конца
Черновик брони сверяет id с базой
Оверлей закрывается на отбое
Фоновая публикация без модалки тарифа
Маркер схемы БД в манифесте
Отказ и «не спрашивали» больше не пустота
Бронь, названная кодом, доходит до брони
Владение ценой оператора на обоих уровнях
🎯 Класс три брата (чип ноги, первая нога, посев серии)
Файл и строка звонка уходят вместе
🎯 Класс 2 → 0, `performCleanup` и `deleteCall`
Модуль звонков пробрасывает отмену
🎯 Класс 146 → 0, гейт стережёт `presentation/call` с потолком 0
🛠️ Попутно — ствол снова зелёный: `ExportWorkPickTest` на общем вырезателе комментариев
Денежные суммы календаря режутся под потолок SQLite
🚨 Календарь отдавал все брони окна (до ±180 дней) в `IN (:bookingIds)` одним списком — на Android 11 при тысяче броней `too many SQL variables` вместо чипов «Долг»/«Оплачено»
🧠 Нарезка живёт в реализациях репозиториев (`queryInChunks`, пачки по 900): защищены все вызывающие `getPaidSumsByBookingIds`/`getInvoiceNetSumsByBookingIds`, а не только календарь; строка результата обоих запросов — один `booking_id` (`GROUP BY`), склейка точная
Экран обслуживания БД не рапортует чужой экспорт
🚨 Подписка на `full_backup_export` падала на `infos.lastOrNull()` и при каждом входе выдавала вчерашний `SUCCEEDED` за свежий — снекбар «Full Backup экспортирован» без единого нажатия, ровно там, куда заходят за копией перед необратимой операцией
🧠 Выбор записи вынесен в `pickReportableExport`: своя работа, незавершённая либо та, что экран видел идущей; чужой завершённый прогон — никогда
🔐 Итог настоящей работы доезжает и тогда, когда `KEEP` отбросил повторный запуск и `trackedExportWorkId` указывает в пустоту (`seenUnfinishedExportIds`); `trackedExportWorkId` — `@Volatile`, его пишут с IO
版本 1.2609.4081
Исправления
Одна таблица подписей оплаты и закрытая партия дефолтов
🌍 Строка «Method» карточки ИИ и семь дефолтов-подписей компонентов больше не показывают русский текст на en-US
🔴 Видимый РУССКИЙ текст карточки изменился для CARD и ONLINE — осознанно, чтобы не заводить шестую таблицу того же enum (подробности в теле фикса)
🛡️ Новый гард «одна таблица подписей», четыре бара с зондами; охват и имя теста приведены к факту по находке ревью
📉 `CyrillicDefaultParamMax` 10 → 3: остаток — данные тенанта, разобран построчно в baseline
🎯 Три пары разных статусов печатались одним словом, теперь таблица одна и все девять различимы
🔐 Побочный регресс защиты от выдумок модели найден ревью и закрыт разведением стороны данных и стороны обвинения; словарь вынесен в свой файл, god-файл стал короче
👀 Три круга ревью, каждый нашёл настоящее; по третьему выводу не согласился и снял вопрос замером
Карточка подтверждения говорит на языке интерфейса
👀 Ревью: сверка всех 17 превью с шаблонами построчно, русский текст дословно прежний; развёл имя-близнец маппера уборки по замечанию ревьюера
🚨 Рядом с честным `QUOTA_EXCEEDED` печаталась строка «first device» — диагноз, обратный происходящему; именно на ней разбор боевого отказа 2026-09-22 ушёл не туда
🧠 Отказ теперь логируется своей веткой с типизированной причиной
💬 Планки нет намеренно: правка меняет ТОЛЬКО диагностическую строку, наблюдаемую лишь в логе; оракул ретеста — logcat при живом отказе по квоте, он расписан в карточке
Отказ приходит ДО смены роли, гард боевых аппаратов выровнен
🚨 Сухой прогон переноса роли БС разбирает конверт настроек: приёмник отказывает на шаге проверки, а не после того, как роль уже уехала на сервер и отменять нечего
🎉 Отдельный код `CONFIG_REJECTED` — отказ больше не утверждает «роль сменилась» там, где она не менялась
🔐 `VerifyLiveDeviceAgents` сторожит троих боевых: добавлен rmx3709 (несёт станцию, в гарде его не было вовсе), убран A5010 (владелец вывел в стендовые 2026-09-22)
📦 Карточка `oneplus5t-tester` — стендовый актор с рутом; заведена `rmx3709-tester` (только чтение)
Подписи ролей и режимов переводятся
🌍 Три энама получили `displayNameRes`; чипы ролей, режим синхронизации и состояние ASR-модели больше не остаются русскими на английском интерфейсе
🧾 Готовая русская строка сохранена отчётам и сообщениям об отказе доступа
🚨 Передача роли базовой станции срывалась на шаге 4 из 7: приёмник не подтверждал нулевую часть, и экран винил в этом «повреждение данных»
🧠 Причина — гонка: оба конца peer-канала отдавали КАЖДЫЙ кадр своей корутине, манифест и часть уезжали врозь, часть читала запись сессии до сохранения манифеста и отбрасывалась молча
📦 Кадр соединения теперь кладётся в его очередь, которую разбирает ровно одна корутина; очередь без предела, чтобы цикл кадров не голодал и pong Ktor разбирался вовремя
🔐 Часть без манифеста получает отказ вместо тишины — страховка на любую перестановку кадров
🧭 Открытое место мастера перестало держаться за мёртвую сессию: решение вынесено чистой функцией, поле сведено к одному замку
💬 Диагноз на экране больше не врёт: «не подтвердили» отделено от «повредилось», а страховая копия называет виноватое устройство
🔍 Отказ отправки поднят с d на w — в релизе R8 вырезает d, и потерянный кадр не оставлял следа вообще
🧾 Шесть новых планок, одиннадцать зондов, два прохода ревью (второй нашёл дыру в самом лекарстве)
✅ Полный ci-check зелёный: 13 гардов и весь набор юнит-тестов
Журнал заговорил на языке интерфейса
🎉 20 записей журнала (пул уборки в карточке комнаты, отмена изменений, календарь цен) уехали в ресурсы
🧠 Закрыта непрозрачная дверь в `UndoViewModel` — упали ОБА потолка ратчета: 120 → 100 и 59 → 58
📦 Подписи полей аудита сведены в один `AuditFieldLabels.kt`: экран и журнал больше не расходятся
🔬 Планка локали среза (6 проверок) и три зонда по одному ограничению на мутанта
🎉 Строка журнала подтягивает остальные номера того же контакта из книги Android
🎯 Гость отдаёт ВСЕ свои телефоны с подписями типа, а не два поля из строки
🚨 Выдача поиска в ветке «звонков по запросу нет» получила свайп — раньше его там не было вовсе
🧼 Строка выдачи определена один раз на обе ветки; `PHONE_CONTACT_TYPES` стал каноном
🎨 Подложка карточки — как у панели долгого тапа (surface 0.95, скругление 20)
💾 Проверено на realme Ultra: контакт с двумя номерами, гость с подписью «Мобильный», оба направления
🧾 10998 юнит-тестов и 14 гейтов зелёные; гард отправляемого текста починен по дороге
Fix/i18n-journal-call-history → beta
🌍 История звонков и обратная связь: 14 записей, остаток presentation 134 → 120
🔴 Русский фолбэк внутри интерполяции вынесен своим ключом
🔬 Первый ключ с ДВУМЯ точками вызова — и планка это сторожит числом, а не фактом
Fix/i18n-journal-room-edit → beta
🌍 Журнал карточки номера следует за языком интерфейса: 8 записей, остаток presentation 142 → 134
🛠️ Отказ удаления номера перестал печатать сырую русскую строку домена — нарушался записанный контракт `RoomHasBookingsException`
🔬 Зондом доказана третья слепая зона: русский, доезжающий АРГУМЕНТОМ, невидим всем десяти планкам программы. Названа в KDoc ратчета, заведена карточкой класса
Улучшения
В списке номеров остались только номера
🧼 Подсказка «Выберите номер» снята: карточка поверх затемнённого списка и так очевидна
🎯 Номера стали ближе к пальцу — меньше ход до нужной строки
💾 Проверено на realme Ultra: и один номер, и два, оба направления
版本 1.2609.4025
Исправления
Fix/i18n-journal-ai-models → beta
🌍 Журнал настроек AI-моделей следует за языком интерфейса: 11 записей, остаток программы по presentation 152 → 142
🧹 Слепая зона `OPAQUE_MAX` впервые уменьшилась: 60 → 59
🔬 Три мутанта, три целевые планки красные, остальные и ратчет зелёные
Улучшения
🔧 Свели prod обратно на линию беты — без форса и без правки защит
📦 Влили `origin/prod` в ствол обратным мержем: содержимого он не несёт, деревья четырёх релиз-мержей идентичны их бета-родителям
🧼 После этого `prod` перематывается на бету обычным пушем, и гард «релиз обязан быть перемоткой» снова выполним
🛡️ Понадобилось потому, что четыре релиза подряд (#347–#350) сделаны мерж-коммитами, и ветки разошлись: перематывать было нечего
💾 Форс-пуш и снятие защиты с `prod` не потребовались