파일·함수 크기 ratchet 게이트로 god 재발을 막다
거대 파일을 한 번 분할하는 건 어렵지만 가능합니다. 진짜 문제는 그다음입니다 — 막지 않으면 또 자랍니다. 그래서 “한 방향으로만 도는 톱니(ratchet)” 방식의 게이트를 커밋 단계에 심었습니다. 줄이는 건 자유, 늘리는 건 차단. AI가 스스로 멈추지 못한다면, 도구가 대신 멈춰 세웁니다. 이 글은 그 ratchet이 정확히 어떻게 작동하는지를 그림과 표로 끝까지 풀어 씁니다.
분할은 끝이 아니라 시작이다
섹션 제목: “분할은 끝이 아니라 시작이다”거대 서비스 파일들을 작은 단위로 쪼개고 나서, 한 가지가 분명해졌습니다. 분할만으로는 부족합니다. 같은 힘 — AI는 새 파일을 만드는 것보다 기존 파일에 덧붙이기를 선호합니다 — 이 그대로 작동하는 한, 애써 분할한 파일도 다시 부풀 게 뻔했습니다. 한 번 청소한다고 끝이 아니라, 다시 어지러워지지 않게 막는 장치가 필요했습니다.
ratchet이 뭔가요 — 한 방향 톱니
섹션 제목: “ratchet이 뭔가요 — 한 방향 톱니”핵심 도구의 이름부터. **ratchet(래칫)**은 한쪽으로만 돌아가는 톱니입니다. 일상에서 이미 많이 씁니다.
코드 크기에 이 발상을 적용하면 규칙은 한 문장으로 끝납니다.
“줄이는 건 자유, 늘리는 건 차단.”
케이블타이가 조이는 쪽으로만 가듯, 코드는 작아지는 쪽으로만 움직일 수 있게 만든 것입니다.
왜 흔한 절대 기준이 아니라 ratchet인가
섹션 제목: “왜 흔한 절대 기준이 아니라 ratchet인가”가장 흔한 방법은 “파일은 300줄을 넘기면 에러”처럼 절대 기준을 거는 것입니다. 그런데 이미 1,000줄짜리 파일이 수십 개인 상태에서 이 규칙을 켜면, 그 순간 전부 빨갛게 터집니다. 아무도 못 켭니다. 켤 수 없는 규칙은 없는 규칙과 같습니다.
ratchet은 발상이 다릅니다. “현재 상태를 인정하되, 악화만 막는다.” 그 차이를 그림으로 보면 분명합니다.
- 이미 큰 파일은 현재 크기를 기준선(baseline)으로 동결합니다 — 그 이상 커지면 차단, 줄이는 건 환영.
- 새로 만드는 파일은 정해진 임계치를 넘으면 아예 커밋이 막힙니다(레거시가 아니니 처음부터 작게).
- 파일 종류별로 임계를 달리합니다 — 예컨대 컨트롤러나 화면 훅처럼 비대해지기 쉬운 종류는 더 엄격하게(약 150줄), 일반 파일은 그보다 느슨하게.
동작을 한 줄씩 — 같은 파일, 세 가지 시나리오
섹션 제목: “동작을 한 줄씩 — 같은 파일, 세 가지 시나리오”실제로 어떻게 판정하는지, 1,104줄짜리 파일 하나를 예로 따라가 보겠습니다(기준선에 “1,104”로 기록돼 있다고 하겠습니다).
| 커밋이 만든 상태 | 기준선과 비교 | ratchet 판정 |
|---|---|---|
| 새 파일이 임계치(예: 300줄)를 넘김 | 레거시 아님 · 신규 | 🚫 차단 — 처음부터 크게 만들지 마라 |
| 1,104줄 파일을 1,150줄로 키움 | 1,150 > 1,104 | 🚫 차단 — “현재 크기”를 동결해 뒀음 |
| 1,104줄 파일을 1,080줄로 줄임 | 1,080 < 1,104 | ✅ 통과 — 기준선도 1,080으로 갱신 |
| 정당한 이유로 일부러 키워야 함 | 명시적 절차 거침 | ✅ 통과(흔적 남김) — 기준선을 다시 잡음 |
맨 아랫줄이 중요합니다. ratchet은 “절대 못 키운다”가 아닙니다. “몰래 키우기는 막고, 결정해서 키우기는 흔적을 남긴다.” 정당한 사유가 있으면 기준선을 다시 잡는 명시적 절차를 거치게 했습니다 — 누가, 왜 늘렸는지가 기록에 남습니다.
커밋 훅에 심는다 — 의지가 아니라 시스템
섹션 제목: “커밋 훅에 심는다 — 의지가 아니라 시스템”이 게이트의 핵심은 “사람의 의지”에 기대지 않는다는 것입니다.
SL.AIMS는 코드를 쓰는 시점과 커밋하는 시점, 두 곳에서 자동으로 크기를 검사하게 했습니다. 의지나 기억이 아니라 시스템이 막으니, “오늘은 좀 봐주자”가 끼어들 틈이 없습니다.
게이트가 단계적으로 자라온 흔적도 기록에 남아 있습니다.
| 시점 | 추가된 것 | 의미 |
|---|---|---|
| 2026-06-05 | 파일 크기 ratchet 설치 | god 파일 재발을 물리적으로 차단 |
| 2026-06-05 | 파일 종류별 임계(컨트롤러·훅 더 엄격) | 비대해지기 쉬운 종류를 더 짧게 묶음 |
| 2026-06-06 | 함수(메서드) 크기 ratchet | 파일을 부풀리는 거대 함수까지 차단 |
파일에서 함수로 — 그리고 둘의 충돌
섹션 제목: “파일에서 함수로 — 그리고 둘의 충돌”처음엔 파일 크기에 ratchet을 걸었고, 바로 다음 날(2026-06-06) 함수(메서드) 크기에도 같은 방식을 적용했습니다. 거대 함수 하나가 파일을 부풀리는 주범이기 때문입니다. 그런데 여기서 한 가지 미묘한 교훈을 또 배웠습니다.
해법은 순서였습니다. 큰 파일 안에서 메서드를 분해해야 할 땐, 파일 분할(facade)을 먼저 하고 그다음에 메서드를 쪼갭니다. 그러면 함수도 작아지고 파일도 줄어, 두 게이트를 동시에 통과합니다. 실제로 이후 세션에서 거대 메서드들을 동작 보존하며 분해해, 함수 크기 위반 개수를 크게 줄여 나갔습니다(한 세션에서 위반 67건 → 44건으로).
처음부터 했어야 할 일
섹션 제목: “처음부터 했어야 할 일”이 모든 ratchet 장치는 프로젝트 첫날 30분이면 세팅할 수 있었습니다. 0줄짜리 프로젝트에 크기 한도를 거는 건 공짜입니다 — 그때부터 모든 파일이 한도 안에서 자랍니다. god 파일 9개를 분할하느라 쓴 시간은 통째로 아낄 수 있었습니다. “나중에 정리하자”는 생각이 정확히 그 god 파일들을 만들었고, 그 “나중”은 늘 더 비싼 모습으로 찾아왔습니다.
이 글은 SL.AIMS를 만들며 겪은 현장 회고 중 하나입니다. 전체 그림은 〈사례연구: SL.AIMS〉에 있고, 이 게이트가 막으려 했던 god 파일 이야기와 함께 읽으면 좋습니다.