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