"저장은 네 폰에서 일어나. 네트워크는 자르고 다시 부를 수 있는 배달원이야. 네 생각이 살아남을지 정하는 건 절대 아니고."
저장은 로컬이야
현장 캡처를 믿을 수 있게 만드는 invariant가 여기 있어. breadcrumb은 어떤 네트워크 sync보다 먼저, 기기에, 로컬로 커밋된다. 저장을 탭하는 순간 생각은 로컬 outbox에 durable하고, 그다음에야 엔진이 Office로 push를 시도해. 죽은 호텔 네트워크든, 비행기 모드든, 닿지 않는 Pippa든 기억을 앗아갈 수 없다는 뜻이야. Office 연결도 Pippa도 저장 임계경로에 절대 없어. 네트워크가 할 일은 이미 안전히 저장된 걸 배달하는 거지, 저장하는 그것 자체가 되는 게 아냐.
outbox state machine
캡처된 breadcrumb은 저마다 명시적 state를 지나. LOCAL_ONLY, QUEUED, SYNCING, SYNCED, FAILED_NEEDS_ATTENTION. 결정적 규칙은 로컬 payload가 idempotent한 서버 승인 전엔 절대 삭제 안 된다는 거야. sync 실패한 crumb은 사라지지도, 조용히 중복 retry하지도 않아. 해결될 때까지 눈에 보이는 failed state에 앉아 있어. 그리고 스트림이 항상 unsynced 수를 드러내니까, PWA 저장이 최종 아카이브가 아니라 staging 영역이라는 걸 한눈에 봐. 아무것도 조용히 안 버려지고, 아무것도 조용히 안 중복돼.
왜 현장에선 idempotency가 중요해
현장 네트워크는 느리기만 한 게 아냐. 모호해. 요청이 나가고, 연결이 죽고, 서버가 받았는지 진짜 몰라. 순진한 수정인 맹목 retry는 중복을 만들어. 첫 게 실제로 도착했으면 같은 crumb 사본이 두 개 되는 거지. Waystone은 crumb마다 안정된 기기-생성 정체성을 줘서, retry가 idempotent야. 서버가 같은 crumb으로 알아보고 두 번째를 안 만들어. 이게 나쁜 연결 뒤에 낫는 outbox랑, 신호 끊길 때마다 기억을 조용히 불리는 것의 차이야.