"이음새 위에 'WhisperKit' 이란 단어가 나타나면, 추상화는 이미 실패한 거야."
어댑터의 유일한 일
STT 어댑터의 일은 자기 엔진을 인터페이스 처럼 보이게 하는 거, 그 이상 아냐. WhisperKit 은 자기 디코딩 옵션, 모델 enum, 오디오 포맷 기대가 있어; whisper.cpp 는 C API 가; SpeechAnalyzer 는 async 결과 스트림이 있어. 그 어느 것도 이음새 위로 새면 안 돼. 각 어댑터가 자기 엔진의 별난 점을 흡수하고 공유 계약만 노출해: 클립과 언어를 줘, 텍스트 더하기 실제 감지한 언어를 돌려줄게. 컨트롤러는 any STTEngine 을 쥐고 어느 것과 얘기하는지 절대 안 배워.
누수 테스트
추상화가 진짜인지 구체적 테스트가 여기 있어: 이음새 위 코드를 엔진-특화 단어로 grep 해. DecodingOptions, WhisperKitConfig, 모델 파일명이 DictationController 에 나타나면, 추상화가 새는 거야 — 컨트롤러가 이제 모른다고 주장한 디테일에 의존해. 깨끗한 어댑터는 그 단어들이 어댑터 파일 안에만 나타난다는 뜻이야. 그 위 전부는 중립 계약을 말해.
누수 (나쁨):
컨트롤러 -> WhisperKit 의 DecodingOptions 직접 읽음 # 엔진이 위로 샘
깨끗 (좋음):
컨트롤러 -> STTEngine.finalize(clip, language) # 중립 계약
WhisperKitEngine -> DecodingOptions 내부에서 만듦 # 별난 점 흡수
계약은 하류가 필요한 걸 담아
반환 타입은 일부러 작지만 완전해: 텍스트, 그리고 엔진이 감지한 언어. 왜 언어? 바로 다음 단계 — 정리 — 가 그걸 필요로 하고, 엔진이 아는 유일한 컴포넌트니까. 어댑터가 언어를 떨구면, 정리가 다시 감지하거나 추측해야 해, 엔진이 이미 푼 문제를 다시 푸는 거야. 좋은 계약은 하류 소비자가 필요한 걸 정확히 담아 그 이상 안 담아 — 엔진 내부 확신 점수도, 토큰 타이밍도 아니라, 앱 나머지가 작동하는 두 사실만.