본문 바로가기
C.W.K.
Stream
← C.W.K. Quests
🔩

Sibling Kit Quest

최근 수정: 2026-10-12

해 지기 전에 앱 셋이 똑같은 배관을 갖게 됐다 — 주인을 하나 붙이고, 발행된 패키지를 거절하고, 나중에 배달을 언어로 가른 저장소

어느 오후, 손이 다른 두 사람이 앱 하나를 본떠 앱 둘을 새로 깔았어. 저녁이 되니 공용 층이 세 벌이었지. 바이트까지 똑같은 클라이언트 라이브러리, 같은 이미지 맞춤 코드를 서로 다르게 두 번 옮긴 것, 같은 행위를 적는 기록 스키마 세 가지, 제각각 어긋나 가는 설정 저장소 셋. 그리고 진짜 버그 하나. 한 시스템의 두 쪽이 이름 하나를 조용히 다르게 부르는 바람에, 모든 앱에서 같은 기능이 동시에 죽었어. 이 퀘스트는 그다음 이야기야. 뭘 지었고, 어떤 답을 골랐는지. 아키텍처 블로그 어디서도 권하지 않는 답이지. 패키지도 아니고 모노레포도 아니고, 이빨 달린 검사를 붙인 복사본.

9 tracks · 48 lessons · ~10.35h · difficulty: intermediate-to-advanced

Level 0흩어진 부품
0 XP0/48 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
중복은 다들 이미 동의하는 유일한 문제야. 그래서 안 죽어. 동의는 추상적이거든. 당연히 같은 코드를 세 벌 갖고 있으면 안 되지. 반면 복사본 하나하나는 구체적이고 싸고, 눈앞의 걸 내보내는 제일 빠른 길이야. 이 저장소가 그랬듯 측정에서 시작해. 하루 만에 부모 하나에서 형제 둘이 태어났고, 몇 시간 뒤 목록을 떠보니 어느 층이 벌써 세 겹인지가 그대로 나와. 거기에 어느 저장소의 테스트도 찾고 있지 않던 앱 사이 버그 하나. 주인 없는 두 쪽 사이에 살았거든. 그 버그가 진짜 논증이야. "유지보수 부담" 같은 말로는 절대 안 꽂히는 값을 보여주거든. 고침은 집이 셋이고, 어긋남은 집이 없어. 그다음이 결정이야. 앱은 따로 간다, 도메인이 진짜로 다르니까. 대신 공용 층은 주인을 딱 하나 갖는다. 거기서부터 따라 나오는 설계를 걸어. 한 걸음 한 걸음 다르게 고를 수도 있었던 것들이야. 배포 모형이 왜 발행된 패키지가 아니라 복사본인지, 그리고 그 답이 왜 여기선 맞고 회사에선 틀릴지. 복사본이 출생증명서를 어떻게 달고 다니는지, 그 증명서가 왜 비교하는 바이트 바깥에 앉아야 하는지. 어긋남 검사가 각 소비자의 자기 테스트에서 돌 때 어떻게 이빨을 얻는지. 파일 경로로 적힌 규칙이 그 파일을 못 두는 저장소 하나를 어떻게 조용히 면제해버렸는지. 그리고 검사가 왜 자기가 어디 서 있는지까지 알아야 하는지도. 어느 기계, 어느 체크아웃인지, git 이 지키는 파일은 뭔지. 이어서 늦은 재검토가 실제로 한 일. 옮기지 않았어. 언어로 갈랐지. 처음 근거가 그대로인 쪽은 복사본으로 남고, 서로 기대는 반은 로컬 경로 패키지가 됐어. 바뀐 건 소비자 수가 아니라 컴파일러였고, 첫 기록엔 그 사실을 적을 칸조차 없었거든. 그리고 경로 패키지가 버전 대신 물리는 값. 그 뒤는 이음매 일이야. 열 이름을 주입하면 스키마 만드는 코드 하나로, 행이 뭘 가리키는지가 서로 다른 앱들을 다 받을 수 있어. 기능 하나를 통째로 끌 땐 갈래를 치는 대신 인자 하나로 끄고. 어떤 큐 모듈도 다른 큐 모듈을 임포트 안 한다는 규율도 있고, 적어둔 예외 목록이 실제에서 멀어지는 동안 매니페스트가 가장자리를 통째로 지켜낸 이야기까지 가. 다음은 키트가 절대 안 넘는 선. 중복을 없애던 바로 그 본능이 도메인 로직까지 끌고 들어오려는 순간, 일부러 반대 방향으로 도는 정규화 둘, 코드와 실행과 공유 상태에 주인을 셋 따로 붙인 판정, 그리고 키트가 그 사실의 주인한테 돌려준 사실들. 그다음은 중복이 실제로 죽는 방식. 세 번째 복사본에서 승격시키고, 중복을 없애려고 만든 저장소 안에 같은 물건의 두 번째 판을 들이지 않고, 인수인계 메모 말고 파일 시스템을 훑어서 세고, 안 들인 것들을 적어둬서 다시 논쟁이 안 열리게 하고, 릴리스 프로그램 사본 여덟을 앱마다 설정을 둔 프로그램 하나로 은퇴시키는 법. 그러고 나면 청구서야. 전환 하나하나가 실제로 얼마였는지. 조용히 사라졌으면 기능 하나가 없어졌을 권한 속성 하나, 그걸 쓰는 앱 둘에서만 확인해서 아홉 앱을 깨뜨린 선택적 슬롯 하나, 그리고 소비 앱들한테서 읽어 온 진짜 실행으로만 값이 매겨진 실행의 이사까지. 마지막은 코드 얘기가 전혀 아닌 규칙들로 닫아. 앱마다가 아니라 한 번 정하는 정책, 끝이 명시된 이주 플래그, 아무도 다시 안 걷게 적어둔 막다른 길, 그리고 얼굴이 어때야 하는지 정하는 주인이 없어서, 한 가족 안에 로봇 아이콘 넷이 따로따로 생겨난 순간. 개념의 오픈소스화: 결과물은 아키텍처지, 네가 클론하는 저장소가 아냐.

Tracks

  1. 01🌆해 지기 전에 세 벌

    0/5 lessons

    저장소 하나를 사들인 측정

    코드 중복을 옹호하는 사람은 없어. 그래서 그걸 두고 다투는 걸로는 아무것도 안 고쳐져. 이 트랙은 대신 재고 조사로 시작해. 어느 오후에 앱 하나를 본떠 앱 둘이 태어났고, 몇 시간 뒤 어느 층이 벌써 세 벌인지를 그대로 적은 목록. 그다음이 "좀 지저분한데"를 아키텍처 결정으로 바꾸는 대목이야. 어느 저장소의 테스트도 찾고 있지 않던 버그. 주인 없는 두 쪽 사이의 어긋남에 살고 있었거든. 잡는 테스트는 한번 쓰고 나면 앱 하나 안에 들어가. 트랙은 거기서 나온 판정으로 닫아. 앱은 따로 간다, 공용 층은 주인이 하나다. 그리고 어떤 모듈이 그 선의 어느 쪽인지를 가르는 질문 하나로. 나중에 한 측정이 질문은 그대로 두고, 적혀 있던 보기 하나만 뒤집는 대목까지.

    Lesson list (5)퀴즈 · 5 문제→
  2. 02📦패키지 말고 복사본

    0/4 lessons

    배포 모형, 그리고 뻔한 답을 거절한 이유

    공용 층에 주인이 생기면 소비자들한테 닿을 길이 필요해지고, 업계엔 답이 하나 있어. 패키지를 발행하고 버전을 고정해라. 이 트랙은 그 답을 이 가족한테 대보고, 왜 거절했는지를 걸어. 상대는 사설 저장소들이야. 결정을 적을 땐 기계 하나 위에서 루프백 형제로 돌았고, 지금은 가족의 모든 맥에 같은 배치 하나로 살고 있지. 그리고 대신 뭘 골랐는지. 스크립트가 배달하는 복사본, 각각이 출처랑 어느 커밋에서 왔는지를 적은 머리말을 달고 다니는 것. 복사본이 뭘 사주는지 (저장소마다 자기 체크아웃만으로 여전히 빌드되고, 갱신마다 소비자 자기 히스토리에 보이게 남고), 뭘 치르는지, 그리고 이게 핑계로 안 굳게 만드는 규율까지. 그 결정은 뒤집어야 할 조건이랑 같이 적혔어. 다음 트랙이 그 조건이 울린 뒤야.

    에디터에 열린 sibling kit 매니페스트. 맨 위 주석은 항목 하나가 키트 파일 하나를 저장소별 복사 대상에 잇는다고 정의하고, 경로는 키트 저장소 루트와 각 소비자 저장소 루트 기준이며, 어떤 파일의 대상에서 빠진 저장소는 그 파일을 그냥 안 받는다고 설명해. 그 아래 consumers 블록은 키트 자신을 첫 줄로, 형제 저장소들이 하나씩 제 상대 경로를 달고 늘어서 있어.
    레지스트리도 패키지 인덱스도 없어. 배포 모델 전체가 누가 뭘 받는지 적은 파일 하나야.
    Lesson list (4)퀴즈 · 4 문제→
  3. 03⚖️두 메커니즘

    0/5 lessons

    언어로 갈라진 재검토

    뒤집을 조건이 울렸어. 소비자 수는 적어둔 선을 한참 넘었고, 늦게 열린 재검토는 전부를 패키지로 옮기지 않았어. 갈랐지. 파이썬이랑 타입스크립트는 복사본으로 남았어. 그 언어들에선 처음 근거가 하나도 안 바뀌었거든. 서로 기대는 스위프트는 로컬 경로 패키지가 됐어. 바뀐 건 수가 아니라 컴파일러였고, 그건 파일 복사본이 담을 수 없는 사실이었거든. 이 트랙은 그 갈라짐을 걷고, 그게 "이제 우린 패키지 해"라는 새 정체성으로 안 굳게 하는 규율, 그리고 경로 패키지가 버전 대신 물리는 유지비까지 봐. 공개 변경은 전부 소비자마다 다음 빌드에 도착해.

    에디터에 열린 공유 키트 매니페스트. 모든 항목이 키트 파일에서 저장소별 벤더 대상으로 간다는 주석, 그 아래 이웃 디렉터리를 적은 소비자 블록. 이 그림은 앞 트랙과 같은 복사 맵이야. 이 트랙이 가르치는 두 번째 메커니즘은 그림 안에 없어.
    그림은 여전히 복사 맵이야. 컴파일러가 쥐는 경로 패키지는 이 트랙의 다른 반이지, 그림이 하나 더 있는 게 아니야.
    Lesson list (5)퀴즈 · 5 문제→
  4. 04🦷이빨 달린 검사

    0/5 lessons

    복사본이 복사본으로 남게 만드는 것

    강제 없는 복사본은 공용 저장소가 끝내려고 태어난 바로 그 상황이야. 그러니까 검사는 이 모형에서 빼도 되는 절반이 아니야. 나머지 절반을 변호할 수 있게 해주는 절반이지. 이 트랙이 그걸 지어. 휘발성 출처 줄을 떼고, 저장소별 템플릿 변수를 비교 뒤가 아니라 앞에 치환하고, 아무도 값을 안 준 자리표시자는 배달을 거부해. 그리고 스크립트를 규칙으로 바꾸는 대목이 와. 전부를 각 소비자 자기 테스트에서 돌려서, 손으로 고친 복사본이 그 저장소 테스트를 깨뜨리게 하는 거야. 되돌리거나 위쪽에서 고칠 때까지. 그다음은 규칙의 진짜 모양을 가르쳐준 실패야. 파일 경로로 적힌 규칙이 그 파일을 못 두는 소비자 하나를 조용히 면제해버렸어. 그리고 마지막은 검사가 서 있는 자리야. 어느 기계, 어느 체크아웃, git 이 지키는 파일은 뭔지, 머리말이 적은 커밋은 뭔지. 나중에 나온 초록 넷이 전부 틀린 트리에 대해 맞았거든.

    Lesson list (5)퀴즈 · 5 문제→
  5. 05🔧갈래 치지 말고 인자로 받아

    0/6 lessons

    구현 하나가 서로 안 맞는 앱들을 섬기는 법

    진짜로 다른 앱들 사이에서 코드를 나눠 쓰려면 결정만으론 안 되고 기법이 필요해. 이 트랙이 이음매 목록이야. 먼저 심. 앱마다 직접 소유하는 몇 줄로, 공용 기계를 자기 상수에 묶어. 다음은 주입되는 열 이름. 행이 대체 뭘 가리키는지가 서로 다른 작업장들을 스키마 만드는 코드 하나로 섬길 수 있게 해줘. 일부러 그 기능이 없는 앱을 위해 기능 전체를 끄는 인자도 있어. 어떤 큐 모듈도 다른 큐 모듈을 임포트 안 한다는 규율, 그리고 처음 기록된 예외랑 그 예외가 치른 값. 코드 속 가장자리는 넷으로 자랐는데 적힌 예외 목록은 하나에 머문 어긋남, 오늘은 다섯이고 그중 하나는 아직 기록에 없다는 것, 그래도 가장자리마다 통째로 배달되게 지켜준 매니페스트 규칙. 마지막은 확장 지점의 두 모양이야. 넘기는 값, 그리고 앱이 뭐든 채우는 슬롯. 슬롯 하나가 공용 컴포넌트를 전혀 안 바꾸고 대화형 표면 하나를 통째로 삼킨 경우까지.

    Lesson list (6)퀴즈 · 6 문제→
  6. 06🚧키트가 절대 안 넘는 선

    0/6 lessons

    중복을 없애던 본능이 해를 끼치기 시작하는 지점

    공용 코드를 쥔 저장소는 끊임없이 끌어당겨. 앱 둘이 비슷한 게 필요할 때마다 제일 싼 수는 공용 자리에 넣는 거고, 그 하나하나가 변호 가능해. 그게 바로 배관 층이 아무도 못 떠나는 프레임워크가 되는 경로고. 이 트랙은 그 경계를 양쪽에서 걸어. 도메인 코드를 밖에 두는 거울 규칙, 일부러 반대 방향으로 돌고 절대 합치면 안 되는 이름 정규화 둘, 어휘를 손으로 베끼는 일이 없게 데이터 파일 하나를 언어 바인딩 셋으로 렌더링하는 것, 그리고 공용 클라이언트가 일부러 얇은 이유. 안 그러면 다시 구현했을 그 절차가 이미 자기 주인한테 살고 있거든. 그다음은 코드가 아예 아닌 나눔의 다른 절반이야. 얇은 클라이언트가 얇게 남게 해주는, 글로 적힌 배선 계약. 마지막은 나중에 생긴 경계 둘이야. 코드, 실행, 공유 상태에 주인을 셋 따로 붙이고 하나뿐이어야 하는 상태한테만 서비스를 허락한 것, 그리고 키트가 사실을 그 사실의 주인한테 돌려준 것.

    Lesson list (6)퀴즈 · 6 문제→
  7. 07⚰️중복이 죽는 법

    0/6 lessons

    승격, 합병, 그리고 훑어서 세기

    추출은 한 번 벌어지고 끝나는 사건이 아니고, 재밌는 건 첫 번째 추출도 아냐. 이 트랙은 그 뒤로 이어지는 실천을 다뤄. 패턴은 언제 승격될 자격을 얻나. 보통은 세 번째 복사본이고, 기다리는 게 일찍 옮기는 것보다 비싼 경우를 위한 이름 붙은 예외가 하나 있어. 평행 관례가 자라서, 승격시키면 중복을 없애려고 존재하는 저장소 안에 같은 물건의 판본 둘을 넣게 되는 지점까지 오면 어떻게 하나. 인수인계 메모랑 파일 시스템이 안 맞을 때 채택자는 어떻게 세나. 일부러 통합 안 하기로 한 것들은 왜 이유랑 같이 적어둬야 하나. 그리고 누가 뭘 쓰는지 적은 원장은 왜 뭐가 어디 배달되는지 적은 매니페스트랑 다른 문서인가. 열이 추가되고 행이 안 늘어나서 그 원장이 조용히 거짓말한 날도 들어 있어. 마지막은 다른 종류의 중복이야. 릴리스 프로그램 하나의 사본 여덟이 각자 다른 가드를 잃었고, 앱마다의 사실은 설정에, 차이는 이름 붙은 훅에 둔 프로그램 하나로 은퇴했어.

    Lesson list (6)퀴즈 · 6 문제→
  8. 08🧾수렴의 값

    0/6 lessons

    채택마다 실제로 얼마였는지, 가정 말고 측정으로

    통합은 보통 추상적으로 논증되고 구체적으로 지불돼. 앱 하나씩. 이 트랙이 청구서야. 제일 싼 것부터 변환하고 첫 번째 값을 적어서, 나머지를 희망이 아니라 견적으로 만드는 법. 설정 컨트롤 셋을 지워야 했던 앱. 똑같은 질문이 다음 앱 셋한텐 아무 값도 안 들었는데 말이야. 조용히 없어졌으면 기능 하나를 데려갔을 권한 속성. 그걸 쓰는 앱 둘에서만 확인해서 소비자 아홉을 깨뜨린 선택적 슬롯. 그리고 버전 붙은 API 가 아니라 같이 배포되는 형제인 가족을 위한 배포 순서 규칙. 규칙을 적을 땐 기계 하나 위 루프백 형제였고, 지금은 모든 맥에 같은 배치 하나야. 그런 가족에선 절반만 배포된 창이 가짜 확신을 찍어내거든. 마지막은 제일 비쌌던 변환, 실행의 이사야. 청구서가 어떤 테스트도 아닌 소비 앱들 자기 실행 일지에서 날아왔어.

    Lesson list (6)퀴즈 · 6 문제→
  9. 09👤사람에 대한 규칙들

    0/5 lessons

    정책, 기본값, 그리고 검사가 못 쥐는 것들

    마지막 트랙은 공용 층에서 코드 문제가 아닌 부분들을 다뤄. 앱마다 다르게 답하고 그 차이를 아키텍처라고 부르는 대신, 주인이랑 같이 정책을 한 번 정하는 것. 이주 플래그를 끝을 명시해서 선언하고, 남은 수를 계속 세서, 조용히 영구 선택이 안 되게 하는 것. 그리고 먼저 삭는 건 그 수라는 걸 보여준 측정. 모든 측정을 만족하면서도 쓰는 사람한텐 여전히 틀리게 읽히는 접근, 그 막다른 길을 적어둬서 아무도 다시 안 걷게 하는 것. 얼굴이 어때야 하는지 정하는 주인이 없어서 한 가족 안에 로봇 아이콘 넷이 따로따로 나타난 날, 그리고 규칙이 아니라 기본값이었던 처방. 마지막으로 공용 배관 저장소가 실제로 뭘 사주고 뭘 치르는지, 그리고 애초에 그게 필요한지에 대한 정직한 시험.

    Lesson list (5)퀴즈 · 5 문제→
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

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

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