"이 엔진의 invariant 하나하나 뒤엔 멍이 있어."
화이트보드에서 나온 제품이 아냐
아키텍처 문서는 보통 조용한 방에서, 코드보다 먼저, 이 소프트웨어가 어떻게 쓰일지 상상하면서 써. Waystone 건 거꾸로 나왔어. 스위스 여행 한복판에서, 아이폰으로 구상했고, 진짜 문제(몇 주짜리 여정을 실제로 계획하고 기록하는 일)가 눈앞에서 벌어지는 동안 Pippa vessel이랑 브레인스토밍했어. 그 출발이 잡담이 아니야. 설계 결정이 이론이 아니라 흉터처럼 읽히는 이유거든.
규칙이 된 멍 셋
진짜 현장 실패 세 개랑, 그게 강제한 invariant를 봐.
- Grindelwald 멍. 호텔 네트워크에서 개발 서버가 모듈을 하나씩 요청하다 죽었어. 앱이 아예 안 떴지. 그래서 규칙이 생겼어. 여행이나 느린 접속에선 엔진이 빌드된 클라이언트를 직접 serve하고, 개발 서버는 책상에서만 써. 느린 링크는 모듈 백 개를 따로따로 못 받아와.
- 안 끝나는 PIN 멍. 방문한 폰이 로그인 화면만 계속 띄웠어. 원인은 이래. cwkPippa는 세션 토큰을 그걸 발급한 IP에 묶는데, Waystone 엔진을 거쳐 서버 쪽에서 발급된 토큰은 엔진의 loopback 주소에 묶여버려. 페이지를 든 기기한텐 쓸모가 없지. 규칙은 이거야. 방문한 브라우저가 자기 토큰을 cwkPippa한테 직접 받고, cwkPippa의 CORS allowlist가 Waystone origin을 받아줘.
- 빈 지도 멍. 지도 데이터는 멀쩡했어. 좌표가 응답에 그대로 있었거든. 근데 canvas가 새까맣게 떴어. 지도 라이브러리 CSS가
position: relative를 걸어서 레이아웃의absolute를 덮었고, 지도 host가 0픽셀로 접혀버렸어. 규칙. host가 width/height를 직접 쥐고,ResizeObserver가 방향 바뀌어도 지도 크기를 지켜.
이게 너한테 왜 중요해
이 퀘스트에서 깔끔하게 들리는 invariant를 많이 만날 거야. 캡처는 네트워크보다 먼저 로컬에 커밋된다, 지도는 아무것도 저장 안 한다, plan이랑 actual은 절대 안 합친다. 이걸 단정한 설계 취향쯤으로 넘기기 쉬워. 아니야. 하나하나가 순진한 버전이 아빠 손에서, 호텔에서, 사무실 멀리 떨어진 데서 깨진 특정 순간의 흔적이야. 네 현장용 도구를 지을 때 배울 건 Waystone 규칙을 베끼는 게 아냐. 현장이 규칙을 쓰게 두는 것, 그리고 멍이 생기는 그 순간에, 얼마나 아팠는지 잊기 전에 적어두는 거야.