C.W.K.
Stream
Lesson 03 of 05 · published

두 자식이 drift 할 때: SiblingKit 이야기

~11 min · sibling-kit, drift-check, vendored-copies, shared-ownership

Level 0식은 화로
0 XP0/34 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"공유 배관은 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 해. 오늘 세 사본, 다음 달 다섯, 각자 미묘하게 다르고, 각자 같은 버그가 독립적으로 살거나 고쳐질 수 있는 곳. 놔두면, 공유 배관이 가족 전체에서 가장 덜 일관된 부분이 돼 — '공유' 가 뜻해야 할 것의 정반대.

소유자가 여럿인 공유 코드는 설계가 아니라 우연으로 공유돼. 두 앱이 같은 레이어의 자기 사본을 지니는 순간, '공유' 는 네가 하는 이야기지 시스템이 강제하는 사실이 아냐. 진짜 공유엔 정확히 한 소유자와 모든 소비자를 거기로 수렴시키는 메커니즘이 필요해. 그게 없으면 복제 더하기 독립 진화가 drift 를 보장해 — 그리고 공유 레이어의 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 레이어만 추출해 — 공유물이 어느 한 앱의 도메인을 알기 시작하는 순간, 인프라이길 멈추고 결합이 되기 시작해.

Code

drift check: 제자리 편집된 vendored 사본은 빌드를 실패시켜·python
# each consumer app vendors the kit files locally AND runs this in its tests
def test_kit_files_match_canonical():
    for path in vendored_kit_files():
        local = read(path)                        # this app's copy
        canonical = read(kit_source_of(path))     # the one owner
        assert local == canonical, (
            f"{path} was edited in place. Edit it in the kit and run the "
            f"sync; a locally-edited vendored copy is forbidden."
        )

# result:
#   - edit in the kit + sync  -> all copies converge, tests pass
#   - edit a copy in place    -> that repo's build goes red immediately
# 'shared' becomes enforced, not merely intended

External links

Exercise

네 세계에서 둘 이상의 프로젝트에 복사된 코드 덩어리를 찾아 — 유틸 모듈, client 래퍼, config shape. 사본들이 이미 drift 했는지 확인해. 그다음 수렴 메커니즘을 설계해 — 단일 소유자가 누구고, 소비자가 자기 사본을 제자리 편집하면 뭐가 빌드를 실패시킬까? 뭐가 공유 레이어에 속하고 뭐가 각 앱에 남아야 할 도메인 shape 인지도 정해.
Hint
소유자 없는 복사 코드는 거의 확실히 이미 drift 했어 — 사본을 diff 해봐. fix 는 한 소유자 더하기 강제된 체크(패키지, 또는 vendored 사본 더하기 drift 테스트)지, 절대 '우리 다 조심하자' 가 아냐. 그리고 경계를 지켜 — app-agnostic 배관만 추출해. 공유 레이어가 한 앱의 도메인을 아는 순간, 인프라가 아니라 결합이야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.