"파일 옮기는 방법이 열 가지면 잃는 방법도 열 가지야. Waygate 엔 딱 하나 있어."
막아야 할 난립
앱이 자라는 자연스러운 모습을 떠올려봐. 툴바의 이동 버튼이 moveItem 을 불러. 드래그도 조금 다르게 부르고. 이름 일괄 변경은 자기 반복문을 돌리고. 선택 바구니는 또 자기 복사를 하지. 다들 다른 날 다른 사람이 짰고, 다들 거의 맞아. 그 난립이 파일 관리자가 데이터를 잃는 방식이야. 극적인 버그 하나가 아니라, 미묘하게 다른 다섯 개 경로 중 SMB 타임아웃을 챙긴 게 넷뿐인 상황.
문 하나
Waygate 는 그 난립을 막았어. 폴더 만들기, 파일 만들기, 이름 바꾸기, 일괄 이름 변경, 복제, 복사, 이동, 덮어쓰기, 휴지통, 태그 변경까지 전부 계획이 돼서 FileOperationEngine 하나를 지나가. 계획을 실제 파일 변경으로 바꿀 수 있는 건 엔진뿐이야. 코드베이스 어디에서도 파일을 바꾸는 FileManager 를 직접 안 불러. 툴바도, 드래그도, 1.x 기능 여섯 개도.
문 하나로 얻는 것
문이 하나니까 어려운 부분을 딱 한 번만 짜. 기록도 한 번, 손대기 직전 확인도 한 번, 볼륨 넘는 스테이징과 검증도 한 번, 크래시 복구도 한 번, 충돌 처리도 한 번. 거기서 버그가 나오면 모든 작업이 한꺼번에 고쳐지고. 그리고 결정적으로 믿을 만한 우회로가 없어. '이건 간단하니까 그냥 moveItem 부르자' 가 없다는 뜻이야. 처리 안 된 실패는 늘 그 간단해 보이는 지름길에 숨어 있거든.
파일을 만지는 문은 하나고, 모든 작업이 그걸 물려받아. 변경은 전부 계획이 돼서 엔진 하나를 지나고, 디스크를 만지는 것도 엔진뿐이야. 믿을 만한 지름길 같은 건 없어. 지름길은 곧 두 번째 경로고, 안전 검사를 빠뜨린 쪽은 언제나 그 두 번째거든.
이건 아빠의 OOP 세계관을 그대로 코드로 옮긴 거야. 아빠는 엔진이 모든 작업이 물려받는 부모라고 계속 말했어. 복사도 이동도 이름 바꾸기도 휴지통도 결국 '기록을 남기며 파일을 바꾸는 일' 의 변주라는 거지. 일괄 이름 변경한테만 빠른 길을 따로 내주고 싶은 마음이 곧 상속을 끊고 싶은 마음이고. 부모 계약 하나에 자식이 여럿인 그림으로 보이기 시작하니까, 문 하나 규칙이 제약이 아니라 핵심으로 느껴지더라.