리치 히키의 클로저 철학—단순성, 불변성, 더 나은 기본값—을 쉽게 풀어 설명합니다. 복잡한 시스템을 더 차분하고 안전하게 만드는 실용적 교훈.

소프트웨어는 한 번에 복잡해지지 않습니다. 마감일을 맞추기 위한 빠른 캐시 하나, 복사를 피하려는 공유 가변 객체 하나, "이건 예외야"라는 이유로 규칙을 깨는 예외 하나씩—이러한 "합리적인" 결정들이 쌓여 어느 순간 변경이 위험하게 느껴지고, 버그 재현이 어려워지며, 기능 추가가 만들기보다 오래 걸리는 시스템이 됩니다.
복잡성이 이기는 이유는 단기적 편안함을 제공하기 때문입니다. 새 의존성을 연결하는 것이 기존 것을 단순화하는 것보다 빠를 때가 많습니다. 상태를 패치하는 것이 상태가 다섯 서비스에 분산된 이유를 묻는 것보다 쉽습니다. 시스템이 문서보다 빨리 커질 때 관습과 조직 내 지식에 의존하기도 쉽습니다.
이 글은 클로저 튜토리얼이 아니며, 클로저를 몰라도 충분히 가치가 있습니다. 목표는 리치 히키의 작업과 자주 연관되는 실용적 아이디어를 빌려와—언어와 상관없이 매일의 엔지니어링 결정에 적용할 수 있는—교훈을 제공하는 것입니다.
대부분의 복잡성은 의도적으로 작성한 코드에서 나오지 않습니다. 도구가 기본으로 쉽게 만들어주는 것에서 옵니다. 기본값이 "모든 곳에서 가변 객체"라면 숨은 결합이 생깁니다. "상태가 메모리에만 존재"라는 기본이 있으면 디버깅과 추적이 어려워집니다. 기본값은 습관을 만들고, 습관은 시스템을 만듭니다.
우리는 세 가지 주제에 집중합니다:
이 아이디어들이 도메인에서 복잡성을 제거하지는 않지만, 소프트웨어가 복잡성을 증폭시키는 것을 막을 수 있습니다.
리치 히키는 클로저를 만든 것으로 잘 알려진 소프트웨어 개발자이자 설계자이며, 흔한 프로그래밍 관행에 도전하는 강연으로 유명합니다. 그의 초점은 유행을 쫓는 것이 아니라 시스템이 변경하기 어렵고, 추론하기 어렵고, 성장하면 신뢰하기 어려워지는 반복적 원인을 탐구하는 데 있습니다.
클로저는 JVM(자바 런타임)이나 자바스크립트 같은 잘 알려진 플랫폼에서 실행되는 현대적 프로그래밍 언어입니다. 기존 생태계를 활용하면서 특정 스타일을 권장하도록 설계됐습니다: 정보를 평범한 데이터로 표현하고, 변경되지 않는 값을 선호하며, “무슨 일이 일어났는가”를 “화면에 무엇을 보여줄지”와 분리합니다.
클로저는 숨은 부작용에서 멀어지게 하고, 더 명확한 구성 블록으로 유도하는 언어라고 생각할 수 있습니다.
클로저는 작은 스크립트를 더 짧게 만들기 위해 만들어진 것이 아닙니다. 반복적으로 발생하는 프로젝트 고통을 겨냥했습니다:
클로저의 기본값은 더 적은 움직이는 부품을 향해 밀어 넣습니다: 안정적인 자료구조, 명시적 업데이트, 조정을 안전하게 만드는 도구들.
가치는 언어 전환에만 국한되지 않습니다. 히키의 핵심 아이디어—불필요한 상호 의존을 제거해 단순화하고, 데이터를 지속 가능한 사실로 다루며, 가변 상태를 최소화하라—는 자바, 파이썬, 자바스크립트 등 어디에서나 시스템을 개선할 수 있습니다.
리치 히키는 단순(simple) 과 쉬움(easy) 을 분명히 구분합니다—그리고 많은 프로젝트가 이 경계를 알아차리지 못하고 넘습니다.
쉬움(easy) 은 지금 느끼는 편의성에 관한 것입니다. 단순함(simple) 은 부품의 수와 그들이 얼마나 밀접하게 얽혀 있는가에 관한 것입니다.
소프트웨어에서 “쉽다”는 종종 “오늘 타이핑하기 빠르다”는 의미이고, “단순하다”는 “다음 달에 고장내기 어렵다”는 의미입니다.
팀들은 즉각적인 마찰을 줄이는 지름길을 선택하는 경향이 있고, 이는 보이지 않는 구조를 추가합니다:
각 선택은 속도로 느껴질 수 있지만, 움직이는 부품, 특수 케이스, 교차 의존성의 수를 늘립니다. 이게 시스템이 극적인 실수 없이도 취약해지는 방식입니다.
빠른 배포는 훌륭할 수 있지만, 단순화 없이 빠르게 진행하면 보통 미래의 빚을 지는 것입니다. 그 이자는 재현하기 힘든 버그, 지체되는 온보딩, "신중한 조정"을 요구하는 변경으로 나타납니다.
설계나 PR을 검토할 때 다음 질문을 하세요:
“상태”는 시스템에서 변할 수 있는 모든 것입니다: 사용자 장바구니, 계정 잔액, 현재 설정, 워크플로 단계 등. 문제는 변화 자체가 아니라 각 변화가 불일치의 새로운 기회를 만든다는 점입니다.
사람들이 “상태가 버그를 만든다”고 말할 때 보통 의미하는 것은: 동일한 정보가 서로 다른 시간(또는 장소)에 다를 수 있으면, 코드가 끊임없이 "지금 어느 버전이 진짜인가?"라는 질문에 답해야 한다는 것입니다. 그 질문을 잘못 대답하면 무작위처럼 보이는 오류가 발생합니다.
가변성은 객체가 제자리에서 편집된다는 뜻입니다: "같은" 것이 시간이 지나며 달라집니다. 효율적으로 보일지 모르지만 추론을 어렵게 만듭니다. 왜냐하면 잠깐 전에 본 것을 더 이상 신뢰할 수 없기 때문입니다.
비유로는 공유 스프레드시트나 문서를 들 수 있습니다. 여러 사람이 동시에 같은 셀을 편집할 수 있다면 이해가 즉시 무효화될 수 있습니다: 합계가 바뀌고, 수식이 깨지고, 행이 사라질 수 있습니다. 누군가 악의적으로 하지 않더라도 공유 가능성과 편집 가능성이 혼란을 만듭니다.
소프트웨어 상태도 마찬가지입니다. 두 부분이 같은 가변 값을 읽으면 한 부분이 아무런 경고 없이 그것을 바꾸고 다른 부분은 오래된 가정으로 계속 진행할 수 있습니다.
가변 상태는 디버깅을 고고학처럼 만듭니다. 버그 리포트가 "데이터가 10:14:03에 잘못 변경되었다"고 알려주지는 않습니다. 단지 잘못된 숫자, 예상치 못한 상태, 가끔만 실패하는 요청 같은 최종 결과만 보입니다.
상태는 시간에 따라 변하기 때문에 가장 중요한 질문은: **어떤 편집들의 연속이 여기로 이끌었는가?**입니다. 그 히스토리를 재구성할 수 없다면 동작은 예측 불가능해집니다:
이것이 히키가 상태를 복잡성 승수로 보는 이유입니다: 데이터가 공유되고 가변적일 때 가능한 상호작용의 수는 우리가 그것들을 정리할 수 있는 능력보다 빠르게 증가합니다.
불변성이란 단순히 생성된 뒤 변경되지 않는 데이터를 의미합니다. 기존 정보를 제자리에서 편집하는 대신, 업데이트를 반영한 새 정보를 만듭니다.
영수증을 떠올려 보세요: 한 번 인쇄된 영수증에서 항목을 지우고 합계를 다시 쓰지 않습니다. 무언가 바뀌면 정정된 영수증을 발행합니다. 이전 영수증은 여전히 존재하고 새 영수증은 명확히 "최신 버전"입니다.
데이터를 조용히 수정할 수 없게 되면 누군가가 뒤에서 몰래 편집할까 걱정할 필요가 줄어듭니다. 그로 인해 일상적 추론이 훨씬 쉬워집니다:
이것이 히키가 단순성에 대해 말하는 큰 부분입니다: 숨은 부작용이 적을수록 추적해야 할 정신적 분기(branch)가 줄어듭니다.
새 버전 생성을 낭비로 느낄 수 있지만 대안과 비교해 보세요. 제자리 편집은 "누가, 언제, 무엇을 바꿨나?"를 묻도록 만듭니다. 불변 데이터에서는 변경이 명시적입니다: 새 버전이 존재하고 이전 것은 디버깅, 감사, 롤백을 위해 남아 있습니다.
클로저는 업데이트를 기존 값을 변이시키는 대신 새 값을 만드는 것으로 다루는 것을 자연스럽게 합니다.
불변성은 공짜가 아닙니다. 더 많은 객체를 할당할 수 있고 "그냥 그것만 업데이트하면 돼"에 익숙한 팀은 적응 기간이 필요합니다. 다행히 현대 구현은 내부적으로 구조를 공유해 메모리 비용을 줄이는 경우가 많고, 보상은 보통 설명하기 어려운 사고가 적은 더 차분한 시스템입니다.
동시성은 단지 "많은 일들이 동시에 일어나는 것"입니다. 수천 요청을 처리하는 웹 앱, 영수증을 생성하면서 잔액을 업데이트하는 결제 시스템, 백그라운드 동기화를 하는 모바일 앱 등은 모두 동시성 상황입니다.
문제는 많은 작업이 같은 데이터를 건드릴 때 발생합니다.
두 작업자가 같은 값을 읽고 수정할 수 있으면 최종 결과는 타이밍에 따라 달라집니다. 이것이 레이스 컨디션입니다: 시스템이 바쁠 때 나타나고 재현이 어렵습니다.
예시: 두 요청이 주문 합계를 업데이트하려 합니다.
아무것도 충돌하진 않았지만 업데이트가 하나 손실되었습니다. 부하가 걸리면 이런 타이밍 창이 더 흔해집니다.
전통적 해결책—락, 동기화 블록, 신중한 순서 지정—은 작동하지만 모든 사람이 조정해야 해서 비용이 듭니다. 조정은 처리량을 낮추고 코드베이스가 커질수록 취약해집니다.
불변 데이터에서는 값이 제자리에서 편집되지 않고, 대신 변경을 나타내는 새 값이 만들어집니다.
이 한 가지 변화가 많은 문제 범주를 제거합니다:
불변성이 동시성을 공짜로 만들지는 않습니다—어떤 버전이 현재인지 결정하는 규칙은 여전히 필요합니다. 그러나 데이터 자체가 움직이는 표적이 아니므로 동시 프로그램은 훨씬 더 예측 가능합니다. 트래픽이 급증하거나 백그라운드 작업이 쌓여도 타이밍 의존적 실패를 볼 가능성이 줄어듭니다.
“더 나은 기본값”은 안전한 선택이 자동으로 발생하고, 추가 위험을 감수하려면 명시적으로 선택해야 한다는 뜻입니다.
작은 것처럼 보이지만 기본값은 월요일 아침 개발자가 무엇을 쓰는지, 금요일 오후 리뷰어가 무엇을 수락하는지, 새 팀원이 처음 코드베이스에서 배우는 것을 조용히 가르칩니다.
“더 나은 기본값”은 모든 결정을 대신하는 것이 아닙니다. 흔한 경로를 덜 오류가 나기 쉬운 방식으로 만드는 것입니다.
예:
이들은 복잡성을 없애지 않지만 확산을 막습니다.
팀은 문서를 따르기보다 코드가 "원하"는 방식을 따릅니다.
공유 상태를 변이하는 것이 쉬우면 그것이 표준 지름길이 되고, 리뷰어들은 안전성에 대해 토론하게 됩니다: "여기서 이게 안전한가?" 반면 불변성과 순수 함수가 기본이면 위험한 동작이 더 눈에 띄어 리뷰어는 논리와 정확성에 집중할 수 있습니다.
즉, 더 나은 기본값은 건강한 기준선을 만듭니다: 대부분의 변경이 일관되게 보이고, 특이한 패턴은 질문하기 쉬울 만큼 명확해집니다.
장기적인 유지보수는 기존 코드를 안전하게 읽고 변경하는 것이 대부분입니다.
더 나은 기본값은 새 팀원이 적은 숨은 규칙(예: "이 함수가 저 글로벌 맵을 은밀히 수정하니 조심하라")으로 인해 고생하지 않게 합니다. 시스템은 추론하기 쉬워져 향후 기능, 수정, 리팩터링의 비용을 낮춥니다.
히키의 강연에서 유용한 사고 전환은 사실(무슨 일이 일어났는가)과 뷰(우리가 현재 믿고 있는 것)를 분리하는 것입니다. 대부분의 시스템은 최신 값만 저장해 어제는 덮어버리므로 시간이 사라집니다.
사실은 불변의 기록입니다: "주문 #4821이 10:14에 접수되었다", "결제 성공", "주소가 변경되었다" 등. 이런 것들은 편집되지 않고 현실이 바뀔 때마다 사실을 추가합니다.
뷰는 앱이 지금 필요로 하는 것: "현재 배송 주소는?" 또는 "고객의 잔액은?" 같은 것입니다. 뷰는 사실들로부터 다시 계산되거나 캐시되거나 인덱싱되거나 물리화될 수 있습니다.
사실을 유지하면 다음을 얻습니다:
레코드를 덮어쓰는 것은 스프레드시트 셀을 업데이트하는 것과 같습니다: 최신 값만 보입니다.
추가만 하는 로그는 수첩의 거래 내역과 같습니다: 각 항목이 사실이고, "현재 잔액"은 항목들로 계산된 뷰입니다.
전체 이벤트 소싱 아키텍처를 채택할 필요는 없습니다. 많은 팀이 작은 규모로 시작합니다: 중요한 변경에 대해 append-only 감사 테이블을 유지하거나, 고위험 워크플로우의 변경 이벤트만 기록하거나, 스냅샷과 짧은 히스토리를 보관하는 식입니다. 핵심은 습관입니다: 사실을 오래 보관하고, 현재 상태는 편리한 투영(projection)으로 취급하세요.
히키의 실용적 아이디어 중 하나는 데이터 우선입니다: 시스템 정보를 평범한 값(사실)으로 다루고, 행위는 그 값들에 대해 실행하는 것으로 생각하세요.
데이터는 지속적입니다. 명확하고 자족적인 정보를 저장하면 나중에 재해석하고, 서비스 간에 이동시키고, 재인덱싱하고, 감사하고, 새로운 기능에 공급할 수 있습니다. 반면 행위는 덜 지속적입니다—코드는 바뀌고 가정이 바뀌며 의존성이 바뀝니다.
이 둘을 섞으면 시스템이 끈적거려집니다: 데이터를 재사용하려면 그것을 만든 행동까지 끌고 가야 합니다.
사실과 행동을 분리하면 컴포넌트들이 데이터 형태에는 동의하지만 공유 코드 경로에 동의할 필요는 없습니다.
리포팅 작업, 지원 툴, 청구 서비스는 동일한 주문 데이터를 소비하면서 각자 로직을 적용할 수 있습니다. 저장된 표현에 로직을 박아넣으면 모든 소비자가 그 내장 로직에 의존하게 되고 변경이 위험해집니다.
깨끗한 데이터(진화하기 쉬움):
{
"type": "discount",
"code": "WELCOME10",
"percent": 10,
"valid_until": "2026-01-31"
}
저장소 안의 미니 프로그램(진화하기 어려움):
{
"type": "discount",
"rule": "if (customer.orders == 0) return total * 0.9; else return total;"
}
두 번째 버전은 유연해 보이지만 데이터 레이어에 복잡성을 밀어넣습니다: 안전한 평가기, 버전 관리 규칙, 보안 경계, 디버깅 도구, 규칙 언어가 바뀔 때 마이그레이션 계획 등이 필요합니다.
저장된 정보가 단순하고 명시적이면 동작을 바꿀 때 역사(history)를 다시 쓰지 않아도 됩니다. 오래된 레코드는 계속 읽을 수 있고, 새 서비스를 추가할 때 레거시 실행 규칙을 "이해"할 필요가 없습니다. 새 UI 뷰, 가격 전략, 분석 등을 도입할 때 새로운 코드를 쓰면 되고 데이터의 의미를 변조할 필요가 없습니다.
대부분의 엔터프라이즈 시스템은 한 모듈이 나빠서 실패하지 않습니다. 모든 것이 서로 연결되어 있기 때문에 실패합니다.
긴밀한 결합은 "작은" 변경이 몇 주간의 재테스트를 촉발하는 방식으로 나타납니다. 한 서비스에 필드를 추가하면 세 downstream 소비자가 깨집니다. 공유 DB 스키마는 조정 병목이 됩니다. 단일 가변 캐시나 싱글턴 설정 객체가 코드베이스의 절반의 의존성이 되는 경우가 생깁니다.
공유된 동일한 변경 가능한 것을 여러 부분이 다루면 그 폭발 반경은 자연스럽게 커집니다. 팀은 더 많은 프로세스, 규칙, 핸드오프를 추가하여 배달을 더욱 느리게 만드는 경향이 있습니다.
언어를 바꾸거나 모든 것을 재작성하지 않고도 히키의 아이디어를 적용할 수 있습니다:
데이터가 발밑에서 바뀌지 않으면 "어떻게 이 상태가 되었지?"라는 디버깅 대신 코드가 무엇을 하는지 더 많이 추론할 수 있습니다.
기본값은 일관성이 스며드는 곳입니다: 각 팀이 각자의 타임스탬프 형식, 오류 모양, 재시도 정책, 동시성 접근을 발명합니다.
더 나은 기본값은 버전 있는 이벤트 스키마, 표준 불변 DTO, 쓰기의 명확한 소유권, 직렬화/검증/추적을 위한 소수의 권장 라이브러리처럼 보입니다. 결과는 놀라운 통합과 일회성 수정이 줄어드는 것입니다.
변경이 이미 일어나는 곳에서 시작하세요:
이 접근법은 시스템을 계속 가동하면서 신뢰성과 팀 조정을 개선하고 범위를 작게 유지해 마무리할 수 있게 합니다.
일상 워크플로가 빠르고 저위험 반복을 지원하면 이러한 아이디어를 적용하기 쉽습니다. 예를 들어, Koder.ai(웹, 백엔드, 모바일 앱용 채팅 기반 바이브 코딩 플랫폼)에서 두 가지 기능은 “더 나은 기본값” 마인드셋과 직접 연결됩니다:
스택이 React + Go + PostgreSQL(또는 모바일은 Flutter)이더라도 핵심 요점은 같습니다: 매일 사용하는 도구가 조용히 기본 작업 방식을 가르칩니다. 추적 가능성, 롤백, 명시적 계획을 일상화하는 도구를 선택하면 순간의 "그냥 패치하자" 압박을 줄일 수 있습니다.
단순성과 불변성은 강력한 기본값이지 도덕 규범이 아닙니다. 시스템이 커질 때 예기치 않은 변경을 줄여주지만 실제 프로젝트에는 예산, 마감, 제약이 있고 때로는 변이성이 적절한 도구입니다.
변이성은 다음과 같은 경우 실용적일 수 있습니다:
핵심은 격리입니다. "가변인 것"이 밖으로 유출되지 않으면 코드베이스 전반에 복잡성이 퍼지지 않습니다.
대부분 함수형 스타일에서도 명확한 소유권이 필요합니다:
이것이 클로저의 데이터와 명시적 경계에 대한 편향이 도움이 되는 점이지만, 이 규율은 언어가 아니라 아키텍처적입니다.
어떤 언어도 잘못된 요구사항, 불명확한 도메인 모델, 또는 무엇이 "완료"인지 합의하지 못하는 팀을 고치지 못합니다. 불변성이 혼란스러운 워크플로를 이해하기 쉽게 만들지 못하고, “함수형” 코드도 잘못된 비즈니스 규칙을 더 깔끔하게 담을 뿐입니다.
프로덕션에 이미 올라와 있다면 이 아이디어들을 전부 혹은 전무로 취급하지 마세요. 위험을 낮추는 가장 작은 움직임을 찾으세요:
목표는 순수성이 아니라 변경당 놀라는 일의 수를 줄이는 것입니다.
이것은 언어, 프레임워크, 팀 구조를 바꾸지 않고도 적용할 수 있는 스프린트 단위 체크리스트입니다.
경계의 데이터 모양을 기본적으로 불변으로 만들기. 요청/응답 객체, 이벤트, 메시지를 한 번 생성하고 수정하지 않는 값으로 다루세요. 변경이 필요하면 새 버전을 만드세요.
워크플로 중간에는 순수 함수를 선호하세요. 하나의 워크플로(예: 가격 계산, 권한, 체크아웃)를 골라 핵심을 읽기-입력 → 출력 데이터로 바꾸세요—숨은 읽기/쓰기 금지.
상태를 더 적고 명확한 장소로 이동시키세요. 개념당 단일 출처(source of truth)를 정하세요(고객 상태, 기능 플래그, 재고 등). 여러 모듈이 자체 복사본을 유지한다면 명시적 동기화 전략을 세우세요.
핵심 사실에 대한 추가 전용 로그를 추가하세요. 한 도메인 영역에 대해 “무슨 일이 일어났나”를 내구성 있는 이벤트로 기록하세요(현재 상태를 동시에 저장해도 됩니다).
API에서 더 안전한 기본값 정의. 기본값은 놀라운 동작을 최소화해야 합니다: 명시적 시간대, 명시적 널 처리, 명시적 재시도, 명시적 정렬 보장 등.
단순성 vs 쉬움, 상태 관리, 값 지향 설계, 불변성, 그리고 시간이 있으면 디버깅과 운영이 어떻게 쉬워지는지에 관한 자료를 찾아보세요.
단순성은 덧붙이는 기능이 아니라 작은, 반복 가능한 선택에서 연습하는 전략입니다.
복잡성은 작은, 지역적으로 타당한 결정들(추가 플래그, 캐시, 예외 처리, 공유 헬퍼 등)이 쌓이면서 발생합니다.
좋은 신호는 “작은 변경”이 여러 모듈이나 서비스에 걸친 동시 수정이 필요하거나, 리뷰어가 안전성을 판단하기 위해 부족한 문서 대신 조직 내 구전 지식에 의존해야 할 때입니다.
지름길은 오늘의 마찰을 줄이는 데 최적화됩니다(출시 속도). 그러나 비용은 미래로 밀려납니다: 디버깅 시간, 조정 오버헤드, 변경 리스크 등.
설계/PR 리뷰에서 유용한 습관은: “이 변경이 어떤 새로운 움직이는 부분이나 특수 케이스를 도입하고, 누가 그것들을 유지할 것인가?”라고 묻는 것입니다.
기본값은 압박 상황에서 엔지니어들이 무엇을 하게 될지를 형성합니다. 변경이 기본값이라면 공유 상태가 널리 퍼집니다. 메모리 중심의 기본값이면 추적 가능성이 사라집니다.
안전한 경로가 가장 쉬운 경로가 되게 하세요: 경계에서의 불변 데이터, 명시적 시간대/널 처리/재시도, 명확한 상태 소유권 등으로 기본값을 개선할 수 있습니다.
상태는 시간이 흐르며 변할 수 있는 모든 것입니다. 문제는 변화가 불일치의 기회를 만든다는 점입니다: 두 컴포넌트가 서로 다른 “현재” 값을 가질 수 있습니다.
버그는 ‘어느 버전의 데이터를 기반으로 동작했나?’라는 질문이 되며, 이 때문에 타이밍 의존적 동작(로컬에서는 동작하지만 프로덕션에서는 불안정) 같은 현상이 나타납니다.
불변성은 값을 생성한 뒤 수정하지 않는다는 뜻입니다. 값을 제자리에서 편집하지 않고, 업데이트를 반영한 새 값을 만듭니다.
실용적으로 유용한 점:
항상 그런 것은 아닙니다. 변이성(mutatability)은 제한될 때 매우 유용합니다:
핵심 규칙은: 가변 구조가 경계를 넘어 누수되지 않도록 하세요. 여러 곳이 읽고 쓸 수 있게 되면 복잡성이 퍼집니다.
레이스 컨디션은 보통 공유된 가변 데이터를 여러 작업자가 읽고 쓴 결과로 발생합니다.
불변성은 작성자가 새 버전을 만들게 함으로써 조정 표면적을 줄입니다. 여전히 어떤 버전이 ‘현재’인지 발행하는 규칙은 필요하지만, 데이터 자체가 이동 표적이 되는 문제는 사라집니다.
사실(facts)은 일단 추가(append-only)되는 불변 기록이고, 뷰(views)는 그 사실들로부터 파생되는 현재 상태입니다.
점진적으로 적용하는 방법:
데이터를 평범하고 명확한 값으로 저장하고, 그 데이터에 대해 동작(behavior)을 수행하세요. 저장소에 실행 가능한 규칙을 넣지 마세요.
이 방식의 장점:
자주 변경되는 하나의 워크플로를 골라 다음 세 가지를 적용하세요:
성공 측정: 불안정한 버그 감소, 변경당 폭발 반경 축소, 릴리스에서의 ‘신중한 조정’ 감소.