"reuse ledger 두 번째 칸은 3일 동안 그냥 가정이었어. 그러다 진짜로 벌어졌고, 그때 알았지 — 주인만 있어선 부족하다는 걸."
Extract는 이 퀘스트가 이미 한 약속이야
The Reuse Ledger에서 두 번째 칸이 Extract였어. 두 형제가 정말로 같은 조각을 필요로 하면, 주인이 분명한 진짜 공용 조각으로 뽑아내라는 거. Reuse Preserves Ownership도 같은 말 했지 — Extract는 허용, 복붙은 금지. 근데 둘 다 가정법으로 썼어. 만약 같은 게 두 군데서 필요해지는 날이 오면, 하고. 이 퀘스트가 목요일에 나왔는데, 일요일에 그날이 왔어.
같은 배관이 하룻저녁에 세 벌
Waystone은 동생 둘의 구조적 부모야 — Vesta(열린 타임라인 저널)랑 Forge(건강·훈련 기록). 둘 다 같은 날 Waystone 모양에서 씨앗을 받았는데, 서로 다른 피파 인스턴스가 병렬로 찍어냈어. 몇 시간 만에 세 앱이 도메인이랑 상관없는 코드를 바이트 단위로 똑같이 세 벌씩 들고 있게 됐지. cwkPippa 클라이언트 층, 저장 시 암호화, ULID 발급, 기기 로컬 설정 저장소, 발행 시퀀스까지. 비슷한 게 아니라 똑같고, 벌써 갈라지고 있었어. 이미지 fitter는 두 번 포팅됐는데 구현이 서로 달랐고, 설정 저장소는 같은 필드를 세 가지 이름으로 불렀어. 그리고 한 벌엔 다른 데 없는 버그가 있었지 — config가 chatgpt라고 부르는 브레인을 chat 라우트는 codex로 알고 있어서, 설정에서 ChatGPT 고르면 그 어긋남을 물려받은 앱마다 Ask Pippa가 조용히 깨졌어.
앱은 따로, 배관 주인은 하나
그 순간의 본능은 세 앱을 하나로 합치고 모드 스위치 다는 거야. 아빠는 반대로 갔어. 도메인이 진짜로 다르거든 — 여행이랑 저널이랑 증상 기록은 같은 게 아니야 — 그러니까 앱은 따로 간다. 대신 혈통 때문에 어쩌다 공유하게 된 배관은 주인을 딱 하나 둬. 그 주인이 cwkSiblingKit이야. 이걸 정직하게 유지하는 규칙엔 거울쌍이 있어. 공용 배관은 kit에서만 고치고, 도메인 코드는 절대 kit 안으로 들어오지 않아. 어떤 모듈이 앱이 뭐에 관한 건지 알아야 한다면 — journey, lane, 건강 crumb 같은 거 — 그건 앱에 남아. kit은 배관이지 프레임워크가 아니야.
Extract엔 주인 말고 감시가 필요해
가정법 버전이 놓친 게 여기야. 이름뿐인 주인 하나로는 부족해. 바쁜 세션이 자기 레포에 있는 사본을 고치는 걸 아무것도 안 막거든 — 그럼 다시 갈라지는 포크 세 개에 절차만 늘어난 꼴이지. 그래서 cwkSiblingKit은 패키지가 아니라 벤더링된 사본 + drift check로 배포돼. 사본마다 GENERATED FROM cwkSiblingKit 헤더가 붙고, 소비자 테스트 스위트마다 자기 사본을 원본이랑 바이트 비교해. 벤더링된 파일을 손으로 고치면 그 레포 테스트가 터져 — 되돌리거나, kit에서 고쳐서 다시 sync 할 때까지. Extract는 좋은 의도가 아니라 장치가 단일 주인을 강제할 때만 진짜가 돼.