
Чому ваш ШІ-нотатник зупиняє запис посеред зустрічі
Наш власний застосунок завершив дві наші зустрічі, поки співрозмовник був на середині фрази. Форензичний слід привів до таймера бездіяльності з добрими намірами, який чув лише вас, — і до другого бага, здатного заблокувати весь робочий стіл. Обидва виправлені в GeekBye v2.0.9.
2 липня GeekBye сам завершив запис зустрічі. Рядок у базі даних каже все: ended_reason = 'idle', тривалість 519 секунд, 99 записів транскрипту — останній записано за дві секунди до того, як застосунок вирішив, що тут нікого немає.
Співрозмовник був на середині пояснення. Останній рядок транскрипту — буквально уривок фрази: «...executes it or turns it on or so—».
Це було не вперше. Напередодні ввечері інша сесія закінчилася так само. Дві зустрічі, вбиті нашою власною функцією надійності. Ось діагноз і фікс, що вийшов у GeekBye v2.0.9, — плюс другий, страшніший баг, який ми виправили в тому ж релізі.
Таймер із добрими намірами, який чув лише вас
Автозакриття через бездіяльність існує не просто так. Люди забувають запис увімкненим на ніч; залишена відкритою вкладка зі зустріччю може вічно цідити звук. Тому GeekBye стежить за неактивністю: після 60 секунд без голосової активності він показує невелике запитання «Still recording?» (усе ще записуємо?), а через 30 секунд без відповіді завершує сесію — чемно все зберігши.
Вада була в одному слові: голосової. Годинник активності рахував лише стійку енергію з мікрофона. Це було свідоме проєктне рішення, і не дурне — врахування сирої енергії системного звуку дозволило б приглушеній, але шумній вкладці тримати мертву сесію живою нескінченно, а це саме та відмова, якій функція має запобігати. Зустрічі, де ви здебільшого слухаєте, мало покривати виявлення вікон зустрічей.
От тільки виявлення зустрічей бачить не кожну зустріч. Вкладки браузера, незвичні клієнти, презентація, яку ви дивитеся, — не розпізнаються. І на нерозпізнаній зустрічі, де ви слухаєте 90 секунд — цілком нормальна річ, поки хтось пояснює свій пайплайн у Databricks, — ви для годинника бездіяльності невідрізнимі від порожньої кімнати.
Погляньте на таймлайн убитої сесії: останній транскрипт з нашого мікрофона прийшов за 68 секунд до кінця. Потім 60 секунд говорив співрозмовник (транскрибовано ідеально, годинником проігноровано), непомічене запитання, 30-секундний відлік і вбивство — через 2 секунди після його останніх слів.
Фікс: транскрипт — доказ життя
Заднім числом виправлення майже незручне: вхідний транскрипт — найсильніший можливий доказ того, що сесія не бездіяльна. Неважливо, хто говорив. Мовленнєва модель щойно розпізнала слова — це і є зустріч.
Тому v2.0.9 оновлює годинник активності на кожному транскрипті, що надходить, з будь-якого боку. Сира енергія системного звуку так само не рахується — музика, гудки очікування та гул вентиляції все ще не можуть увічнити мертву сесію, а жорсткий ліміт тривалості запису так само підстраховує все. Лише розпізнане мовлення тримає сесію живою — і це саме та межа, яка потрібна.
Одна деталь із код-рев'ю, якою варто поділитися: перша версія фікса оновлювала годинник усередині шляху атрибуції мовця — який частина транскриптів може легітимно пропускати. Рев'ю впіймало, що майбутня зміна могла б мовчки повернути баг саме для тих транскриптів, які важливі (співрозмовника). Тепер оновлення безумовне, до будь-якого розгалуження, з тестом, який падає, якщо хтось його зсуне.
Той самий реліз виправив дещо страшніше
Тестуючи ці фікси, ми наткнулися на інший баг найжорсткішим способом: збій процесу інтерфейсу залишив весь робочий стіл некликабельним.
Оверлей GeekBye — прозоре вікно поверх усіх вікон, що покриває екран. За замовчуванням воно пропускає кліки; інтерфейс перемикає його в інтерактивний режим, коли ви користуєтеся панеллю. Ці перемикання надходять із процесу інтерфейсу — тож коли той процес упав із відкритою панеллю, невидиме вікно лишилося в інтерактивному режимі без живого UI за ним. Кожен клік по робочому столу потрапляв у мертву невидиму панель. Єдиним виходом було примусово закрити застосунок.
Обробник збоїв у v2.0.9 тепер негайно повертає пропуск кліків і перезавантажує інтерфейс — із лімітом у три перезавантаження на хвилину, щоб цикл збоїв не міг крутитися вічно (після ліміту застосунок припиняє перезавантажувати, але робочий стіл лишається придатним до роботи — а це і є головне). Код-рев'ю відточило і цей фікс: відновлення обмежене саме вікном оверлея, бо огульне ввімкнення пропуску кліків у впалого звичайного вікна — скажімо, діалогу оновлення — створило б зворотне блокування.
Ви можете перевірити цей фікс самі, жорстко: відкрийте панель GeekBye, примусово завершіть процес «GeekBye Helper (Renderer)» у Моніторингу системи і подивіться, як застосунок повертає вам робочий стіл протягом секунди.
Чого нас навчила ця пара багів
- Будь-яка непряма ознака «користувач тут?» десь відмовляє. Енергія мікрофона відмовляє на слухачах. Виявлення вікон відмовляє на браузерах. Розпізнані транскрипти відмовляють на... ми поки не знайшли, на чому, бо це не непряма ознака — це сам продукт.
- Усьому, що керується рендерером, потрібен сценарій на випадок збою. Якщо мертвий процес UI може залишити по собі стан на рівні ОС (захоплення миші, поверх усіх вікон, захист контенту), скиданням має володіти головний процес.
- Бути власним найактивнішим користувачем — це стратегія пошуку багів. Обидва баги вдарили по нас на справжніх зустрічах раніше, ніж їх помітила більш ніж жменька клієнтів. Колонка
ended_reason, додана заради спостережуваності за місяці до того, перетворила діагноз на запит до бази даних замість вгадування.
Обидва фікси пройшли шлях від діагнозу до випущеного нотаризованого релізу за один день, кожен — у відрев'юєному PR з регресійними тестами. Якщо ви на GeekBye v2, вони у вас із v2.0.9 через автооновлення.
Решту історії цього релізу читайте в сусідній статті серії чому ШІ-транскрипція перекручує технічні терміни (v2.0.11), у фундаменті надійності в статті чому ваш ШІ-нотатник зупиняється на поганому Wi-Fi і в тому, як оверлей лишається невидимим під час демонстрації екрана, не крадучи ваші кліки.


