"날짜는 crumb 이 읽히는 곳이야. ULID 는 crumb 이 무엇인가고. 라벨을 물건으로 착각하지 마."
절대 합쳐지지 않는 두 날짜
crumb 은 비슷해 보이지만 절대 하나로 뭉개지면 안 되는 두 날짜를 실어. captured_at(그리고 captured_local_date, timezone)은 불변 캡처 진실이야. 아빠가 적은 진짜 순간이지. target_date 는 그가 지정하는 소유 날짜야. 파일링하고 읽을 때 crumb 이 속하는 날이고. 앞 레슨이 이 분리를 썼다면, 이번 건 왜 그게 invariant 인지 이름을 붙여. 적는 순간과 속하는 날은 다른 사실이야. 하나만 저장하는 설계는 결국 다른 하나에 대해 거짓말하고.
ULID 가 정체성이다
어느 날짜도 crumb 의 정체성이 아냐. 모든 crumb 은 불변의 device-생성 ULID 를 갖고, 그게 그것이 무엇인가야. 날짜, 파일명, 제목은 그 위에 얹힌 presentation·sorting 메타데이터고. 이건 뭔가를 바꿔야 하는 순간 중요해져. 정체성이 날짜가 아니라 ULID 니까, crumb 을 다른 날로 옮겨도 새 crumb 이 안 생겨. 같은 것에 revision 을 덧붙일 뿐이야. 물건은 이름을 지키고 라벨만 바뀌고.
왜 edit-in-place 가 아니라 append-only revision 인가
delete-and-recreate 는 '엉뚱한 날에 파일했다' 의 유혹적인 지름길인데, 여기선 정확히 틀렸어. crumb 의 정체성, 캡처 진실, 이미 붙은 interpretation 을 다 버리거든. append-only revision 은 셋 다 지켜. 같은 ULID, 같은 captured_at, 그리고 새 target_date. 옛 날짜는 revision 흔적에 그대로 보이고. folded state 는 현재 날짜를 보이고, journal 은 가졌던 모든 날짜를 기억해. 그 규율, 그러니까 projection 은 바꾸되 history 는 절대 안 지운다는 것, 이게 Track 7 의 저장 층 전체를 다스리는 바로 그 규율이야.