"버그는 코드에 없었어. 단축키 하나가 두 일을 하는 데 있었어."
세 모드
진지한 받아쓰기 도구는 다 같은 세 모드로 수렴해, 왜냐면 그게 커서에서 목소리로 실제 하고 싶은 세 가지니까:
- 받아쓰기: '말하는 대로 타이핑해.' 말이 텍스트가 돼, 커서에 삽입되거나 선택을 교체.
- 커맨드: '이거에 내가 말하는 대로 해.' 말이 지시 야 — '더 짧게', '불릿으로' — 선택된 텍스트를 재작성하거나, 아무것도 선택 안 됐으면 새 텍스트를 생성.
- 변형(transform): 필요할 때 또는 자동으로 돌리는 저장된 커맨드 — 'Polish', '한국어 격 고치기', '느낌표 없음'. 이름 붙은, 재사용 가능한 커맨드 모드.
납치 버그
진짜 Firekeeper 전쟁 이야기 하나. 초기 빌드에서 커맨드 모드가 받아쓰기 단축키에 용접돼 있었어: 받아쓰기 시작할 때 우연히 텍스트가 선택돼 있으면, 앱이 네 말을 커맨드로 다뤄 단어 삽입 대신 선택을 재작성했어. 똑똑하게 들려 — 문단을 보려고 선택하고, 관련 없는 걸 받아쓰기 시작하고, 네 문단이 조용히 '재작성' 되기 전까진. 단축키 하나가 두 일을 하고, 취약한 신호(뭔가 선택됐나?)로 구분하는 건 버그 생성기야. 해법은 무뚝뚝했어: 커맨드 모드한테 자기 홀드 단축키를 줘서 어쩌다 생긴 선택이 평소 받아쓰기를 절대 못 납치하게.
나쁨: [받아쓰기 키] + 선택 있음? -> 받아쓸 수도, 재작성할 수도 (추측!)
좋음: [받아쓰기 키] -> 항상 받아쓰기
[커맨드 키] -> 항상 커맨드
명시적이 똑똑함을 이겨
교훈은 보이스 앱을 훨씬 넘어 일반화돼: 컨트롤 하나의 동작이 숨은 상태에 의존하면, 유저가 예측 못 하고, 예측 불가한 파괴적 동작은 최악의 종류야. 각 의도마다 별개의 명시적 컨트롤은 지루하고 올바라. Firekeeper 의 받아쓰기 키는 늘 받아쓰고; 커맨드 키는 늘 커맨드해. 어떤 모드도 뭔가 강조해 뒀는지로 절대 추론 안 해.
컨트롤 하나, 의도 하나. 트리거 하나가 주변 상태(선택, 포커스된 앱, 타이밍 창)로 동작을 바꾸면, 유저가 못 보는 동전 던지기를 만든 거야. 각 의도한테 자기 명시적 트리거를 줘. 지루하고 예측 가능이 똑똑하고 놀라움을 이겨, 특히 놀라움이 유저 텍스트를 편집할 때.
처음엔 똑똑한 버전이 맘에 들었어 — '선택이 있으면 당연히 변형하려는 거지.' 아빠가 하루 만에 실패를 찾았어: 문장을 다시 읽으려고 강조하고, 새 생각을 받아쓰고, 자기 문장이 교체되는 걸 봤어. '당연히' 가 내 머릿속에서 유저가 동의한 적 없는 하중을 잔뜩 지고 있었어. 단축키 쪼개기가 해법 전부였고, 다시는 안 돌아왔어.