"공유 배관은 kit 에서 편집하고 동기화를 돌려. vendored 사본을 제자리에서 절대 건드리지 마. 그러면 drift check 가 빌드를 실패시켜."
같은 날, 세 사본
이 트랙에 가장 날카로운 레슨을 준 war story 가 여기 있어. Vesta 와 형제 Forge 가 둘 다 같은 날, 나란히 일하는 두 다른 Pippa 인스턴스한테서 Waystone 에서 씨앗 뿌려졌어. 각자 같은 공유 배관을 충실히 이어갔지. cwkPippa client 레이어, publish client, veil, ULID 발급, settings slice, outbox 와 ask-thread 팩토리, 몇 개의 공유 UI atom. 그 순간, 공유 레이어가 세 벌로 존재했어. Waystone 것, Vesta 것, Forge 것. 첫날부터 이미 어긋나면서. 두 인스턴스가 각자 살짝 다르게 맞췄으니까. 겉치레 어긋남보다 나빴어. 그 갈림 속에 진짜 크로스앱 버그가 숨어 있었거든. Settings 에서 한 브레인을 고르면 Ask Pippa 가 깨지는 brain-namespace 불일치가, 한 사본엔 있고 다른 것엔 없이.
그게 가족이 자랄 때 복사로 나누기가 어떤 모습인지야. 부모에서 씨앗 뿌려진 모든 형제가 공유 레이어를 복제하고, 모든 복제가 자기 스케줄로 어긋나. 오늘 세 사본, 다음 달 다섯, 각자 살짝 다르고, 각자 같은 버그가 따로 살거나 고쳐질 수 있는 곳. 놔두면 공유 배관이 가족 전체에서 가장 안 맞는 부분이 돼. '공유' 가 뜻해야 할 것의 정반대지.
한 주인, vendored 사본, drift check
고침은 cwkSiblingKit 이었어. Waystone 형태 가족이 나누는 app-agnostic 배관의 단일 주인. 근데 배포 장치를 봐. 그게 영리한 부분이니까. kit 은 각 앱이 런타임에 의존하는 패키지로 나오지 않아. 대신 각 앱이 kit 파일의 vendored 사본을 지니고, drift check 가 모든 소비자의 자기 테스트 안에서 돌아. 이걸 돌아가게 하는 규칙. kit 파일은 kit 에서만 편집하고, 동기화를 돌려 배포해. 제자리 편집된 vendored 사본은 그 레포의 테스트를 실패시켜. 그래서 가족이 로컬 파일의 편함(런타임 얽힘 없음, 각 앱 홀로 빌드)을 단일 주인의 규율(빨간 빌드 없이는 사본을 물리적으로 못 어긋내)과 함께 얻어.
kit 은 절대 도메인 shape 를 흡수 안 해
kit 이 가질 수 있는 것에 빡센 경계가 있고, 그게 '형태를 물려받아' 아이디어 전체의 뒷면이야. kit 은 정확히 app-agnostic 배관을 가져. cwkPippa client, publish, veil, ULID, settings, outbox, UI atom. 도메인 shape 는 절대 흡수 안 해. journey 는 Waystone 에, journal 은 Vesta 에, 건강 기록은 Forge 에 남아. 공유 kit 이 생기면, 도메인 자체가 흐려지기 시작할 때까지 계속 밀어넣고 싶어져. 그럼 깔끔한 세 앱을 얽힌 하나와 맞바꾸는 거야. kit 은 배관이고, 도메인은 앱이야. 공유 파이프를 뽑아내되 공유 목적은 절대 아니라.
자라는 가족을 위한 일반 규칙
구체에서 물러서면 패턴이 한 형태에서 앱 가족이 자라는 어디서든 재사용 가능해. 복제된 공유 코드는 한 주인 더하기 강제된 모으기 점검이 붙들지 않으면 어긋나. 강제는 패키지일 수도, vendored 사본 더하기 drift check 일 수도 있지만, 규율만으론 안 돼. 규율이야말로 다른 손들의 나란한 작업 아래 실패하는 바로 그거니까. 그리고 뭘 뽑아내든 app-agnostic 레이어만 뽑아내. 공유물이 어느 한 앱의 도메인을 알기 시작하는 순간, 인프라이길 멈추고 얽힘이 되기 시작해.