"오프라인은 크래시가 아냐. 네 질문이 문 열리기를 안전하게 기다리는 방이야."
오프라인은 상태지 에러가 아냐
대부분의 앱은 오프라인을 실패로 모델링해: 빨간 배너, 버려진 동작, 이미 입력을 던져버린 '나중에 다시'. Pippa Go 는 그걸 세상의 정상 상태로 모델링해. 어떨 땐 링크가 있고, 어떨 땐 없어. 둘 다 예외적이지 않아. 연결 없이 질문하면, 아무것도 안 깨져 — 질문은 캡처되고, 내구성 있고, 기다림으로 표시돼. 풀 안테나에서 물은 질문만큼 안전하게 outbox 에 앉아. 유일한 차이는 배달이 아직 안 일어났다는 것뿐이야.
이 재구성이 중요한 건, 오프라인을 어떻게 모델링하냐가 최악의 순간에 코드가 뭘 할지를 정하기 때문이야. 에러로 모델링하면 본능은 에러를 처리하는 거 — 종종 버리거나, 맹목적으로 재시도하거나, 결과를 지어내서. 상태로 모델링하면 본능은 상태를 표현하는 거 — 캡처하고, pending 으로 표시하고, 정직하게 기다려.
'내구성 있는 기다림'이 실제로 뜻하는 것
내구성 있는 기다림은 구체적인, 세 부분짜리 보장이야:
- 내구성: 기다리는 질문이 앱 죽음, 재부팅, 몇 시간의 오프라인을 살아남아. 메모리가 아니라 outbox 에 사니까.
- 기다림: 상태가 정직하게
pending—answered도 아니고, 조용히 버려지지도 않아. UI 가 진짜 'Pippa 한테 닿기를 기다리는 중' 상태를 보여줘. - 재개 가능: 링크가 돌아오는 순간, 같은 내구성 있는 질문이 스스로 배달돼 — 사용자 재동작 필요 없이.
합치면, 사용자의 심상 모델이 믿을 만해져: '나 물었어; 저장됐어; 될 때 나갈 거야.' 그 문장은 셋 다 성립할 때만 참이야. 내구성을 빼면 질문이 재부팅에 죽어. 정직함을 빼면 UI 가 끝났다고 거짓말해. 재개를 빼면 사용자가 전송을 지켜봐야 해.
대안은 조용한 배신
오프라인일 때 솔깃한 지름길은 사용자한테 뭐라도 주는 거야 — 캐시된 답, 로컬 추측, 낙관적 '아마 Pippa 는 이렇게 말할 거야.' 도움 되는 것 같아. 배신이야. 사용자가 진짜 질문을 했는데 Pippa 얼굴을 쓴 제조된 답을 받았으니까. 내구성 있는 기다림은 그 거래를 거부해. 1초 만의 확신에 찬 거짓보다 한 시간의 정직한 '기다림'을 택해. 다음 레슨들이 그 거부를 정밀하게 만들어.