
AI 노트테이커는 왜 회의 중간에 녹음을 멈추는가
우리 앱이 상대방이 한창 말하는 도중에 우리 회의 두 건을 스스로 끝내버렸습니다. 포렌식 추적의 끝에는 당신 목소리밖에 듣지 못하던, 선의로 만든 유휴 타이머가 있었고 — 데스크톱 전체를 잠가버릴 수 있는 두 번째 버그도 나왔습니다. 둘 다 GeekBye v2.0.9에서 고쳤습니다.
7월 2일, GeekBye가 회의 녹음을 스스로 끝냈습니다. 데이터베이스 행이 모든 것을 말해줍니다: ended_reason = 'idle', 지속 시간 519초, 전사 엔트리 99개 — 마지막 엔트리는 앱이 아무도 없다고 판단하기 2초 전에 기록됐습니다.
상대 참가자는 한창 설명 중이었습니다. 전사 기록의 마지막 줄은 말 그대로 문장 조각입니다: "...executes it or turns it on or so—".
처음도 아니었습니다. 전날 저녁, 또 다른 세션이 같은 방식으로 끝났습니다. 회의 두 건이 우리 자신의 안정성 기능 손에 죽은 겁니다. 여기 그 진단과 GeekBye v2.0.9로 출시된 수정이 있습니다 — 같은 릴리스에서 고친, 더 무서운 두 번째 버그와 함께요.
당신 목소리만 들을 수 있었던 선의의 타이머
유휴 자동 종료가 존재하는 데는 좋은 이유가 있습니다. 사람들은 녹음을 밤새 켜둔 채 잊어버리고, 열어둔 채 방치된 회의 탭은 오디오를 영원히 조금씩 흘려보냅니다. 그래서 GeekBye는 비활성을 감시합니다: 유성(voiced) 활동 없이 60초가 지나면 작은 "Still recording?"(아직 녹음 중인가요?) 프롬프트를 띄우고, 30초가 더 지나도 응답이 없으면 세션을 끝냅니다 — 모든 것을 저장하면서, 정중하게.
결함은 한 단어에 있었습니다: 유성. 활동 시계는 지속적인 마이크 에너지만 카운트했습니다. 그건 의도적인 설계 결정이었고, 멍청한 결정도 아니었습니다 — 시스템 오디오의 원시 에너지를 카운트하면 음소거됐지만 시끄러운 탭이 죽은 세션을 무한정 살려둘 수 있는데, 그게 바로 이 기능이 막으려고 존재하는 실패니까요. 대부분 듣기만 하는 회의는 회의 창 감지가 커버하기로 되어 있었습니다.
다만 회의 감지가 모든 회의를 볼 수는 없습니다. 브라우저 탭, 특이한 클라이언트, 보고만 있는 프레젠테이션 — 감지되지 않습니다. 그리고 감지되지 않은 회의에서 90초 동안 듣기만 하면 — 누군가 자기 Databricks 파이프라인을 설명하는 동안이라면 지극히 정상적인 행동이죠 — 유휴 시계에게 당신은 빈 방과 구별되지 않습니다.
죽은 세션의 타임라인을 확인해 보세요: 우리 마이크에서 나온 마지막 전사는 종료 68초 전이었습니다. 그다음 상대방이 말하는 60초(완벽하게 전사됐지만 시계에게는 무시됐습니다), 눈치채지 못한 프롬프트, 30초 카운트다운, 그리고 종료 — 상대의 마지막 말이 나오고 2초 뒤였습니다.
수정: 전사는 살아 있다는 증거다
돌이켜 보면 민망할 정도로 간단한 교정입니다: 들어오는 전사는 세션이 유휴 상태가 아니라는 가장 강력한 증거입니다. 누가 말했는지는 중요하지 않습니다. 음성 모델이 방금 단어를 인식했다는 것 — 그것이 곧 회의입니다.
그래서 v2.0.9는 어느 쪽에서 오든, 도착하는 모든 전사에 활동 시계를 찍습니다. 시스템 오디오의 원시 에너지는 여전히 카운트되지 않습니다 — 음악, 대기음, 공조기 소음은 여전히 죽은 세션을 불멸로 만들 수 없고, 녹음 하드 캡이 여전히 모든 것을 마지막에 받쳐줍니다. 오직 인식된 음성만이 세션을 살려두는데, 그것이 정확히 올바른 경계선입니다.
코드 리뷰에서 나온, 전할 만한 디테일 하나: 수정의 첫 버전은 화자 귀속 경로 안에서 시계를 찍었습니다 — 그런데 일부 전사는 그 경로를 정당하게 건너뛸 수 있습니다. 리뷰는 미래의 변경이 정확히 문제가 되는 전사(상대 화자의 것)에 대해서만 버그를 조용히 재도입할 수 있다는 점을 잡아냈습니다. 스탬프는 이제 어떤 분기보다도 앞에서 무조건 찍히며, 누가 옮기면 실패하는 테스트가 붙어 있습니다.
같은 릴리스에서 더 무서운 것도 고쳤습니다
이 수정들을 테스트하다가 다른 버그를 호되게 만났습니다: 인터페이스 프로세스의 크래시가 데스크톱 전체를 클릭 불가로 만들어버린 겁니다.
GeekBye의 오버레이는 화면을 덮는 투명한 최상위(always-on-top) 창입니다. 기본값은 클릭 통과(click-through)이고, 패널을 사용할 때 인터페이스가 그것을 인터랙티브로 토글합니다. 그 토글은 인터페이스 프로세스에서 오는데 — 패널이 열려 있는 동안 그 프로세스가 크래시하자, 보이지 않는 창은 뒤에 살아 있는 UI도 없이 인터랙티브 모드에 갇혔습니다. 데스크톱에 하는 모든 클릭이 죽은, 보이지 않는 판 위에 떨어졌습니다. 유일한 탈출구는 앱 강제 종료였습니다.
v2.0.9의 크래시 핸들러는 이제 클릭 통과를 즉시 복원하고 인터페이스를 다시 로드합니다 — 크래시 루프가 영원히 돌지 못하도록 분당 리로드 3회 상한과 함께요(상한을 넘으면 앱은 리로드를 포기하지만 데스크톱은 계속 쓸 수 있는데, 중요한 건 바로 그 부분입니다). 코드 리뷰가 이 수정도 벼려줬습니다: 복구는 오버레이 창에만 한정됩니다. 크래시한 일반 창 — 예컨대 업데이트 대화 상자 — 에까지 클릭 통과를 일괄 적용하면 정반대 방향의 잠금을 만들었을 테니까요.
이 수정은 직접, 거칠게 검증해 볼 수 있습니다: GeekBye 패널을 열고, 활성 상태 보기(Activity Monitor)에서 "GeekBye Helper (Renderer)" 프로세스를 강제 종료한 뒤, 앱이 1초 안에 데스크톱을 되살리는 것을 지켜보세요.
이 버그 한 쌍이 가르쳐준 것
- "사용자가 여기 있는가?"의 모든 프록시는 어딘가에서 실패합니다. 마이크 에너지는 듣기만 하는 사람에게 실패합니다. 창 감지는 브라우저에서 실패합니다. 인식된 전사가 실패하는 경우는... 아직 찾지 못했습니다. 프록시가 아니라 제품 그 자체이기 때문입니다.
- 렌더러가 주도하는 모든 것에는 크래시 시나리오가 필요합니다. 죽은 UI 프로세스가 OS 수준의 상태(마우스 캡처, 최상위 창, 콘텐츠 보호)를 남길 수 있다면, 리셋의 책임은 메인 프로세스가 져야 합니다.
- 스스로 가장 무거운 사용자가 되는 것은 버그 발견 전략입니다. 두 버그 모두 소수의 고객이 눈치채기 전에 실제 회의에서 우리를 먼저 때렸습니다. 몇 달 전 관측 가능성을 위해 추가해 둔
ended_reason컬럼 덕분에 진단이 추측이 아니라 데이터베이스 쿼리가 됐습니다.
두 수정 모두 진단에서 서명·공증된 릴리스 출시까지 하루 안에 끝났고, 각각 리그레션 테스트를 실은 리뷰된 PR로 진행됐습니다. GeekBye v2를 쓰고 있다면 v2.0.9부터 자동 업데이트로 이미 적용되어 있습니다.
이 릴리스의 나머지 이야기는 같은 시리즈의 이웃 글 AI 전사가 기술 용어를 잘못 알아듣는 이유(v2.0.11), 안정성의 기초 작업을 다룬 나쁜 Wi-Fi에서 AI 노트테이커가 멈추는 이유, 그리고 오버레이가 클릭을 훔치지 않으면서 화면 공유 중에 보이지 않게 유지되는 방법을 참고하세요.


