C.W.K.
Stream
Lesson 04 of 04 · published

모드는 고르는 거지 추측하는 게 아냐

~11 min · connection-modes, explicit, privacy, tailscale

Level 0불씨 없음
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"네 목소리가 어디로 가는지는 네가 내린 결정이어야지, 네트워크가 대신 내린 결정이면 안 돼."

세 모드, 하나의 선택

Firekeeper 의 정리 브레인은 세 곳에 살 수 있고, 유저가 어느 걸 골라 — 숨은 폴백 체인이 아니라 설정이야:

  • Pippa Full — This Mac: localhost 의 cwkPippa. 풀 볼트, 소울, 브레인 라우팅.
  • Pippa Full — Tailscale: 같은 풀 Pippa, 설정된 호스트로 가는 사설 Tailscale 링크로 도달. 같은 능력, 원격 전송, 인증-게이트.
  • Local Mini — Ollama: 컴팩트한 Pippa-맛 정리 프로토콜을 돌리는 작은 로컬 모델. cwkPippa 아예 없음.

"This Mac" 과 "Tailscale" 은 같은 능력의 두 전송 이고; "Local Mini" 는 다른, 가벼운 능력이야. 유저가 트레이드오프를 명시적으로 골라.

왜 자동 폴백이 아냐?

이걸 조용한 체인으로 만들고 싶어져: This Mac 시도, 그다음 Tailscale, 그다음 Local Mini, 그다음 결정론적. 그 조용한 체인이 프라이버시 버그야. 오프라인-전용 자세를 일부러 고른 유저는 localhost 가 잠깐 도달 불가라고 오디오가 조용히 원격 호스트로 라우팅되면 절대 안 돼. 풀-Pippa 품질을 기대한 유저는 조용히 약한 로컬 결과를 받으면 절대 안 돼. 그래서 프로바이더 선택이 요청 전송 전에, 고른 모드에 맞춰 일어나 — 그리고 고른 타깃이 실패하면, 앱이 유저 등 뒤에서 하나 고르는 대신 대안을 제안 해(재시도, 다른 Full 타깃으로 전환, Local Mini 로 내림, 원시 삽입).

조용한 폴백 (나쁨):  오프라인 유저 -> localhost 다운 -> 조용히 Tailscale 침  # 누수!
명시적 선택 (좋음):  오프라인 유저 -> localhost 다운 -> "재시도? / Local Mini? / 원시?"

무는 디테일 둘

원격 모드는 주의가 필요해. 연결 모드 변경은 원격 인증/세션 상태를 무효화 해 — Tailscale PIN 세션을 This-Mac 요청으로 못 끌고 가. 그리고 모든 원격 호출은 유저가-취소-가능한 제한 시간이 필요해: 음성 캡처가 멈춘 원격 경로를 기다리며 절대 매달리면 안 돼. 쓴 경험에서 온 규칙 하나 더: 원격 호스트를 절대 하드코딩하지 마. Firekeeper 는 설정 가능한 호스트 필드를 소유해; 한 기계 주소를 박으면 이식 가능한 앱을 한-Mac 앱으로 바꿔.

명시적 의도로 라우팅하고, 실패 시 대안을 제안해. 프라이버시 민감한 건 뭐든, 목적지는 유저가 내리고 볼 수 있는 결정 — 절대 일시적 실패의 자동 결과가 아냐. 고른 모드에 맞춰 프로바이더를 미리 선택하고; 실패 시 다른 프라이버시/품질 자세를 조용히 대체하는 대신 선택지를 드러내.
멈춘 원격이 보이스 루프를 절대 얼리면 안 돼. Tailscale 정리 호출이 매달리면, 단축키-부터-삽입 루프 전체가 그걸 기다릴 수 없어. 모든 원격 요청을 제한 시간으로 묶고 진행 중 작업을 취소 가능하게 만들어, 나쁜 네트워크가 유저 단어를 인질로 잡은 얼어붙은 앱 대신 '원시 삽입 제안' 으로 격하되게.

Code

전송 전에, 고른 모드에서 프로바이더 결정·swift
enum ConnectionMode { case pippaFullThisMac, pippaFullTailscale, localMiniOllama }

func provider(for mode: ConnectionMode, hosts: HostSettings) -> CleanupProvider {
    switch mode {
    case .pippaFullThisMac:   return CwkPippaProvider(baseURL: hosts.localhost)
    case .pippaFullTailscale: return CwkPippaProvider(baseURL: hosts.tailscaleHost)  // 설정 가능!
    case .localMiniOllama:    return OllamaMiniPippaProvider(baseURL: hosts.ollama)
    }
}

// 프로바이더는 요청 전에 유저 모드에서 골라져.
// 실패 시 앱이 선택지를 제안; 절대 조용히 자세를 안 바꿔.
// hosts.tailscaleHost 는 설정이지 하드코딩 주소 절대 아님.

External links

Exercise

서비스를 로컬로도 원격으로도 도달할 수 있는 앱에 대해, 조용한 폴백 체인과 대안-제안-명시적-선택의 차이를 써봐. 조용한 체인이 유저가 안 물어보고 벌어졌다는 걸 알면 화날 구체적 케이스 하나를 묘사해.
Hint
화나는 케이스는 거의 항상 프라이버시야: 오프라인이라 믿은 유저가 로컬 타깃이 깜빡였다고 데이터가 원격 호스트로 갔다는 걸 발견. 조용한 폴백은 '계속 작동함' 에 최적화; 명시적 선택은 '내가 허가 안 한 일이 내 데이터에 안 벌어짐' 에 최적화. 목소리엔 두 번째가 유일하게 받아들일 기본값이야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.