[G1-Sync] Manual knowledge update

This commit is contained in:
Antigravity Agent
2026-05-10 22:08:15 +09:00
parent 21ac3ed255
commit 504fd5fb42
3011 changed files with 380280 additions and 206977 deletions
+244 -154
View File
@@ -2,189 +2,279 @@
id: wiki-2026-0508-code-smells
title: Code Smells
category: 10_Wiki/Topics
status: needs_review
status: verified
canonical_id: self
aliases: []
aliases: [코드 악취, code smell, refactoring catalog, Fowler, bloater, coupler, dispensable]
duplicate_of: none
source_trust_level: A
confidence_score: 0.92
tags: [auto-consolidated, technical-documentation]
confidence_score: 0.93
verification_status: applied
tags: [refactoring, code-smell, fowler, software-quality, technical-debt, oop, code-review]
raw_sources: []
last_reinforced: 2026-05-08
last_reinforced: 2026-05-10
github_commit: pending
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
tech_stack:
language: unspecified
framework: unspecified
language: language-agnostic
framework: refactoring catalog
---
# [[코드 악취 식별과 리팩토링 징후 (Code Smells)]]
# Code Smells
## 📌 한 줄 통찰 (The Karpathy Summary)
No summary available.
## 📌 한 줄 통찰
> **"매 code 의 surface 의 sign 의 deeper problem"**. Martin Fowler 의 catalog. 매 syntax 의 OK 가, 매 design 의 ill. 매 refactoring 의 trigger. 매 modern: 매 SonarQube / Semgrep / AI review 의 자동 detect.
## 📖 구조화된 지식 (Synthesized Content)
소스 코드에 명시된 리팩토링 카탈로그에 따르면, 코드 악취는 코드베이스를 읽고 구조를 파악하는 데 방해가 되는 여러 가지 패턴으로 분류됩니다 [4, 5]. (※ 소스에는 각 코드 악취에 대한 구체적인 작동 원리나 상세 설명은 부족하며, 주로 분류 체계 및 목록 위주의 정보가 제공됩니다.)
## 📖 핵심
* **비대화 (Bloaters)**
코드가 시간이 지남에 따라 통제하기 어려울 정도로 커진 상태를 뜻합니다.
* 긴 메서드 (Long Method), 거대한 클래스 (Large Class), 원시 타입 집착 (Primitive Obsession), 긴 매개변수 목록 (Long Parameter List), 데이터 군집 (Data Clumps) 등이 포함됩니다 [4, 5].
* **객체지향 남용 (Object-Orientation Abusers)**
객체지향 프로그래밍의 원칙을 불완전하게 적용했거나 잘못 활용한 경우입니다.
* 스위치 문 (Switch Statements), 임시 필드 (Temporary Field), 거부된 유산 (Refused Bequest), 다른 인터페이스를 가진 대체 클래스 (Alternative Classes with Different Interfaces)가 있습니다 [4, 5].
* **변경 방해자 (Change Preventers)**
코드의 한 부분을 수정할 때 시스템의 다른 많은 부분도 함께 수정해야만 하게 만드는 구조적 악취입니다.
* 뒤엉킨 변경 (Divergent Change), 산탄총 수술 (Shotgun Surgery), 평행 상속 계층 (Parallel Inheritance Hierarchies)이 속합니다 [4, 5].
* **불필요한 요소 (Dispensables)**
코드베이스에 존재할 이유가 없으며, 오히려 가독성을 떨어뜨리고 용량만 차지하는 요소입니다.
* 불필요한 주석 (Comments), 중복 코드 (Duplicate Code), 게으른 클래스 (Lazy Class), 데이터 클래스 (Data Class), 죽은 코드 (Dead Code), 추측성 일반화 (Speculative Generality) 등이 해당합니다 [4, 5].
* **결합기 (Couplers)**
클래스 간의 결합도를 과도하게 높여서 모듈화를 저해하는 요소입니다.
* 기능 편애 (Feature Envy), 부적절한 친밀도 (Inappropriate Intimacy), 메시지 체인 (Message Chains), 미들맨 (Middle Man)이 포함됩니다 [4, 5].
* **기타 악취**
* 불완전한 라이브러리 클래스 (Incomplete Library Class) [4, 5].
### 매 Fowler 의 6 category
이러한 코드 악취들은 코드 분석 도구(Code Analysis Tools)에 의해 식별될 수 있으며, 이를 정리하면 더 적은 버그, 더 나은 유지보수성, 팀의 생산성 증가라는 결과를 가져옵니다 [2].
#### 1. Bloater
- **Long Method**: 매 single function 의 거대.
- **Large Class**: 매 god class.
- **Primitive Obsession**: 매 string / int 의 abuse.
- **Long Parameter List**: 매 4+ parameter.
- **Data Clump**: 매 같이 쓰이는 data 의 group X.
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
*※ 소스에 코드 악취 해결(리팩토링) 자체에 대한 명시적인 부작용이나 제약 사항이 깊이 있게 서술되어 있지는 않습니다. 다만 코드 분석 및 리팩토링의 맥락에서 다음 사항들을 유추 및 확인할 수 있습니다.*
#### 2. OO Abuser
- **Switch Statement**: 매 polymorphism 의 missed.
- **Temporary Field**: 매 일부 case 만 의 사용 field.
- **Refused Bequest**: 매 inherit 가, 매 일부 의 X.
- **Alternative Classes with Different Interface**: 매 same job, 매 다른 method name.
* **오탐(False Positives)으로 인한 피로감:** 코드 악취나 취약점을 잡기 위해 자동화된 코드 스캐닝 도구를 무분별하게 사용할 경우, 잘못된 경고(False Positives)가 과도하게 발생할 수 있습니다. 이는 개발자의 신뢰를 떨어뜨리고 리뷰에 불필요한 시간을 낭비하게 만드는 부작용(Alert Fatigue)을 낳을 수 있습니다 [6-9].
* **성능과 개발 속도 저하:** 코드 악취를 찾기 위한 도구가 파이프라인 성능에 영향을 주거나 통합이 원활하지 않으면 시스템 릴리스 주기를 지연시키고 개발자의 경험을 저해할 수 있습니다 [9, 10].
* **섣부른 추상화 경계:** '추측성 일반화'와 같은 악취를 예방하기 위한 지나친 리팩토링이나, 코드 악취인 '중복 코드'를 제거하기 위한 조기 추상화는 오히려 코드의 복잡성을 가중시킬 수 있습니다 [11].
#### 3. Change Preventer
- **Divergent Change**: 매 1 class 의 매 다른 reason 의 수정.
- **Shotgun Surgery**: 매 1 변경 의 매 N class 의 수정.
- **Parallel Inheritance Hierarchies**: 매 두 hierarchy 의 동시 의 grow.
## 🔗 지식 연결 (Graph)
- [[Refactoring]]: 코드 악취를 제거하기 위한 구체적인 기술적 해법.
- [[Technical_Debt]]: 코드 악취를 방치했을 때 축적되는 결과물.
- [[Clean_Code]]: 코드 악취가 없는 상태의 지향점.
#### 4. Dispensable
- **Duplicate Code** (DRY violation).
- **Lazy Class**: 매 도움 X.
- **Data Class**: 매 anaemic (case-by-case).
- **Dead Code**: 매 unused.
- **Speculative Generality**: 매 hypothetical 의 design.
- **Comments**: 매 reason 의 explain 의 X 의 case.
---
#### 5. Coupler
- **Feature Envy**: 매 method 의 다른 class 의 더 사용.
- **Inappropriate Intimacy**: 매 internal 의 over-share.
- **Message Chain**: `a.b().c().d()` 의 chain.
- **Middle Man**: 매 delegation 만.
### Related Concepts
#### 6. Other
- **Mysterious Name**: 매 unclear identifier.
- **Magic Number**: 매 unnamed constant.
- **Insider Trading**: 매 inappropriate field access.
- **Incomplete Library Class**.
#### [분석 및 탐지 도구 (Analysis & Detection Tools)]
- [[코드 분석 도구 (Code Analysis Tools)]]
- 연결 이유: 코드 악취, 논리적 오류, 유지보수성 문제 등을 소스 코드 내에서 식별하여 가시성을 제공하는 핵심 도구입니다 [1, 2].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 정적 분석(SAST) 방식이 어떻게 코드베이스를 실행하지 않고도 잠재적 악취를 잡아내어 버그를 방지하는지 이해할 수 있습니다 [1].
### 매 modern addition (Fowler 2nd ed)
- **Mutable Data**.
- **Global Data**.
- **Loops** (Stream / functional 의 lieu).
- **Repeated Switches**.
- [[SonarQube]]
- 연결 이유: 지속적인 코드 품질 검사를 통해 버그와 '코드 악취(Code Smells)'를 탐지하는 대표적인 솔루션입니다 [3, 12].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 멀티 언어 환경에서 CI/CD와 결합하여 코드의 건강도를 유지하는 방법론을 파악할 수 있습니다 [3].
### 매 detection
- **Manual review**.
- **Linter**: ESLint, RuboCop, Pylint.
- **SAST**: SonarQube, CodeClimate.
- **Semgrep**: 매 custom rule.
- **AI review**: CodeRabbit, Greptile.
#### [코드 개선 및 구조화 (Code Improvement & Structuring)]
- [[리팩토링 (Refactoring)]]
- 연결 이유: 소스에 나열된 코드 악취들(비대화, 객체지향 남용 등)을 실제로 해결하고 코드를 재구성하기 위한 실천적 접근법입니다 [4, 5].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 코드 악취를 없애기 위해 '메서드 추출(Extract Method)'이나 '메서드 이동(Move Method)' 같은 기법이 어떻게 적용되는지 구체적으로 알 수 있습니다 [4].
### 매 refactoring (corresponding)
- **Extract Method**: Long Method.
- **Extract Class**: Large Class.
- **Replace Conditional with Polymorphism**: Switch.
- **Move Method**: Feature Envy.
- **Hide Delegate**: Message Chain.
- **Introduce Parameter Object**: Long Parameter / Data Clump.
- [[DRY (Don't Repeat Yourself) 원칙]]
- 연결 이유: 코드 악취 중 하나인 '중복 코드(Duplicate Code)'를 원천적으로 방지하기 위한 소프트웨어 아키텍처 핵심 원칙입니다 [4, 13].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 지식이나 로직을 단일화하여 유지보수성 및 시스템 안정성을 높이는 논리적 추상화 방식을 이해할 수 있습니다 [13, 14].
### 매 priority
- 매 not all smells 의 fix 의 immediate.
- 매 changing area 의 first.
- 매 boy scout rule (better than found).
### Deeper Research Questions
## 💻 패턴
- 정적 코드 분석 도구(Static Code Analysis)가 코드 악취를 감지할 때 흔히 발생하는 오탐(False Positive)을 줄이기 위한 맥락 기반 탐지 기술은 무엇인가?
- 코드베이스의 '변경 방해자(Change Preventers)' 악취가 마이크로서비스 아키텍처로의 클라우드 마이그레이션 및 확장성에 미치는 영향은 무엇인가?
- '거대한 클래스'와 '긴 메서드' 같은 비대화(Bloaters) 악취를 리팩토링할 때, 어떤 객체 지향 설계 원칙(예: 단일 책임 원칙)을 기준으로 책임을 분리해야 하는가?
- 대규모 레거시 시스템에서 아무도 손대지 못해 악취가 심하게 남아있는 코드 블록을 탐색하고 점진적으로 리팩토링하는 효과적인 방법론은 무엇인가?
- AI 기반 코드 리뷰 도구(예: CodeRabbit, Qodo)는 기존 룰 기반 정적 분석 도구가 찾기 힘든 결합기(Couplers) 계열의 복잡한 코드 악취를 어떻게 추론하고 해결책을 제시하는가?
### Long Method (extract)
```ts
// ❌ Long Method
function processOrder(order: Order) {
// 매 50+ lines: validate, calculate, save, notify, log...
}
### Practical Application Contexts
// ✅ Extract Method
function processOrder(order: Order) {
validate(order);
const total = calculateTotal(order);
save(order, total);
notify(order);
}
- **Implementation:** 코드를 작성할 때부터 긴 매개변수나 임시 필드 남용을 자제하여 객체지향 남용(Object-Orientation Abusers)이나 비대화(Bloaters) 악취가 코드베이스에 유입되지 않도록 합니다.
- **System Design:** 도메인 주도 설계나 클린 아키텍처를 도입하여 시스템의 책임을 분리함으로써, 산탄총 수술이나 부적절한 친밀도(Inappropriate Intimacy)와 같은 구조적인 코드 악취 발생을 최소화합니다.
- **Operation / Maintenance:** CI/CD 파이프라인에 SonarQube, Cycode 등과 같은 분석 도구를 통합하여 새롭게 추가되는 커밋이나 풀 리퀘스트에서 코드 악취를 지속적으로 식별하고 걸러냅니다.
- **Learning Path:** 새로운 코드베이스에 적응(Onboarding)할 때, 의도적으로 악취가 짙은 코드(가장 오랫동안 리팩토링되지 않은 덩어리)를 파고들어 팀원들에게 그 구조의 설계 역사와 제약을 질문하는 탐색 도구로 활용할 수 있습니다 [15].
- **My Project Relevance:** 현재 소프트웨어 프로젝트에서 점진적인 리팩토링을 수행하기 위해 코드 분석 툴을 도입하여 중복 코드 및 쓸모없는 코드(Dispensables)를 최우선으로 제거합니다.
### Adjacent Topics
- [[기술적 부채 (Technical Debt)]]
- 확장 방향: 코드 악취가 적절히 해소되지 않고 누적될 경우 팀의 개발 속도를 늦추고 아키텍처를 부패하게 만드는 기술적 빚의 개념으로 학습을 확장합니다.
- [[정적 애플리케이션 보안 테스트 (SAST)]]
- 확장 방향: 코드 악취 식별을 넘어, 애플리케이션 보안 취약점을 소스 코드 수준에서 탐지하는 보안 지향적 스캐닝 기법으로 확장합니다.
- [[SOLID 원칙]]
- 확장 방향: 객체지향 설계 남용(Object-Orientation Abusers) 및 높은 결합도(Couplers) 악취를 방지하기 위한 구조적 설계 지침을 학습합니다.
---
*Last updated: 2026-05-02*
## 1. 개요
코드 악취(Code Smells)는 프로그램 소스 코드 내에 존재하는 심각한 문제는 아니지만, 더 깊은 구조적 결함이나 향후 문제를 야기할 수 있는 잠재적인 징후들을 의미한다. 켄트 벡(Kent Beck)과 마틴 파울러(Martin Fowler)에 의해 대중화된 이 개념은, '직관적으로 무언가 잘못되었다'는 느낌을 주는 코드 패턴들을 분류하고 이에 대응하는 구체적인 리팩토링 기법을 연결해준다.
## 2. 주요 코드 악취 분류
- **비대화 (Bloaters)**: 클래스나 메서드가 시간이 지남에 따라 너무 커져서 관리하기 힘든 상태.
- *예: 긴 메서드(Long Method), 거대 클래스(Large Class), 데이터 뭉치(Data Clumps).*
- **객체 지향 남용 (Object-Orientation Abusers)**: 객체 지향의 원칙을 잘못 적용한 경우.
- *예: 복잡한 switch 문, 거부된 유산(상속받은 기능을 전혀 사용 안 함).*
- **변경 방해 요소 (Change Preventers)**: 한 곳을 수정하면 연관된 수많은 곳을 같이 고쳐야 하는 구조.
- *예: 산탄총 수술(Shotgun Surgery), 분기되는 수정(Divergent Change).*
- **불필요한 요소 (Dispensables)**: 존재 가치가 없거나 삭제해도 무방한 코드.
- *예: 중복 코드, 죽은 코드(Dead Code), 무의미한 주석.*
- **잘못된 결합 (Couplers)**: 클래스 간의 과도한 의존성.
- *예: 기능 편애(다른 클래스의 데이터를 과도하게 사용), 메시지 체인.*
## 3. 엔지니어링 가치
- **리팩토링의 이정표**: 코드를 언제, 어디서부터 고쳐야 할지 모를 때 코드 악취는 가장 명확한 우선순위와 리팩토링의 타겟을 제공함.
- **기술 부채 조기 탐지**: 심각한 버그나 아키텍처 붕괴로 이어지기 전에 문제의 징후를 발견하여 유지보수 비용을 획기적으로 낮춤.
- **공통의 설계 언어**: 팀 내에서 "이 메서드는 산탄총 수술 스멜이 나네요"와 같은 용어를 사용하여 코드 리뷰 시 설계 결함에 대해 구체적이고 전문적인 의사소통 가능.
## 4. 트레이드오프 및 주의사항
- **주관적 판단의 영역**: 무엇이 '악취'인지는 팀의 숙련도나 프로젝트의 맥락에 따라 달라질 수 있음. 기계적인 룰 적용보다는 팀 내 합의된 품질 기준이 중요함.
- **성급한 수정의 위험**: 단순히 악취가 난다고 해서 즉시 고치는 것이 항상 최선은 아님. 기능 구현이 급하거나 영향 범위가 너무 넓은 경우 전략적인 '기술 부채'로 남겨두는 판단도 필요.
- **도구의 한계**: 정적 분석 도구가 많은 악취를 잡아낼 수 있지만, '기능 편애'나 '잘못된 상속' 같은 논리적 스멜은 개발자의 통찰력 있는 코드 리뷰를 통해서만 발견 가능.
## 🧪 검증 상태 (Validation)
- **정보 상태**: 검증 완료 (Verified)
- **출처 신뢰도**: A
- **검토 이유**: 소프트웨어의 노후화를 방지하고 지속 가능한 구조를 유지하기 위해 설계상의 허점을 포착하는 핵심 렌즈인 '코드 악취' 체계 정립.
## 📌 Brief 정 요약
코드 악취(Code Smells)는 애플리케이션의 유지보수성 문제, 논리적 오류, 그리고 전반적인 코드 품질 저하를 나타내는 소스 코드 내의 징후입니다 [1, 2]. 이러한 악취는 버그의 온상이 될 수 있으며, 지속적인 품질 검사 도구(예: SonarQube) 등을 통해 조기에 발견할 수 있습니다 [2, 3]. 코드 악취를 식별하고 리팩토링을 통해 해결하는 것은 장기적으로 안정적인 제품을 만들고 팀 간의 원활한 협업을 가능하게 하는 핵심 과정입니다 [2, 4, 5].
## 🧪 검증 상태 (Validation)
- **정보 상태:** draft
- **출처 신뢰도:** A
- **검토 이유:** Datacollector에서 자동 추출된 위키 데이터의 초기 통합.
## 🧬 중복 검사 (Duplicate Check)
- **기존 유사 문서:** None
- **처리 방식:** CREATE
- **처리 이유:** 신규 지식 체계 도입
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
**언제 이 지식을 쓰는가:**
- *(TODO)*
**언제 쓰면 안 되는가:**
- *(TODO)*
## 🕓 변경 이력 (Changelog)
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|------|-----------|-----------|--------|
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
## 💻 코드 패턴 (Code Patterns)
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
```text
# TODO
function validate(order: Order) { ... }
function calculateTotal(order: Order) { ... }
```
## 🤔 의사결정 기준 (Decision Criteria)
### Primitive Obsession → Value Object
```ts
// ❌
function transfer(amount: number, currency: string) { ... }
**선택 A를 써야 할 때:**
- *(TODO)*
// ✅
class Money {
constructor(public amount: bigint, public currency: string) {}
add(other: Money) {
if (this.currency !== other.currency) throw new Error();
return new Money(this.amount + other.amount, this.currency);
}
}
**선택 B를 써야 할 때:**
- *(TODO)*
function transfer(money: Money) { ... }
```
**기본값:**
> *(TODO)*
### Switch → Polymorphism
```ts
// ❌
function area(shape: Shape) {
switch (shape.type) {
case 'circle': return Math.PI * shape.r ** 2;
case 'square': return shape.side ** 2;
case 'rectangle': return shape.w * shape.h;
}
}
## ❌ 안티패턴 (Anti-Patterns)
// ✅
abstract class Shape { abstract area(): number; }
class Circle extends Shape { constructor(public r: number) {} area() { return Math.PI * this.r ** 2; } }
class Square extends Shape { constructor(public side: number) {} area() { return this.side ** 2; } }
```
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
### Feature Envy → Move Method
```ts
// ❌
class Order {
total(customer: Customer) {
// 매 모든 logic 의 customer 의 사용
return customer.discount * customer.tax * ...;
}
}
// ✅ Move to Customer
class Customer {
applyDiscount(amount: number) { return amount * this.discountRate; }
}
```
### Message Chain → Hide Delegate
```ts
// ❌ Chain
order.getCustomer().getAddress().getCountry().getName();
// ✅ Hide
class Order {
customerCountry() {
return this.customer.address.country.name;
}
}
```
### Detection (Semgrep)
```yaml
# 매 long parameter list detection
rules:
- id: long-parameter-list
pattern-either:
- pattern: function $F($A, $B, $C, $D, $E, ...) { ... }
message: "Function has 5+ parameters — consider Parameter Object"
severity: WARNING
languages: [typescript, javascript]
```
### SonarQube quality gate
```properties
# 매 cognitive complexity
sonar.javascript.cognitive-complexity-threshold=15
# 매 duplicate threshold
sonar.cpd.minimumLines=20
sonar.duplicatedLines.maximum=3.0
```
### AI review (CodeRabbit)
```yaml
# .coderabbit.yaml
language: en
reviews:
profile: chill
high_level_summary: true
poem: false
auto_review:
enabled: true
drafts: false
# 매 auto-detect: long methods, missing tests, complexity, etc.
```
### Refactor metric (cyclomatic complexity)
```bash
# 매 radon (Python)
radon cc src/ -a -nb
# 매 ESLint complexity rule
echo '{ "rules": { "complexity": ["error", 10] } }' > .eslintrc.json
```
### Bobby tables (refactor cadence)
```python
# 매 boy scout rule
def visit(file):
if needs_change(file):
# 매 main change
do_main_change()
# 매 small refactor (touching area)
if has_smell(file):
small_refactor()
```
## 🤔 결정 기준
| Smell | Refactor |
|---|---|
| Long Method | Extract Method |
| Large Class | Extract Class |
| Primitive Obsession | Value Object |
| Long Parameter | Parameter Object |
| Duplicate | DRY (Extract) |
| Switch | Polymorphism |
| Feature Envy | Move Method |
| Data Clump | Class |
| Comments (bad) | Rename / Restructure |
| Magic Number | Named Constant |
**기본값**: 매 fix-as-you-touch + 매 priority queue (changing area).
## 🔗 Graph
- 부모: [[Refactoring]] · [[Code-Quality]] · [[Software-Engineering]]
- 변형: [[Bloater]] · [[Coupler]] · [[Dispensable]] · [[Change-Preventer]]
- 응용: [[Extract-Method]] · [[Replace-Conditional-with-Polymorphism]] · [[Move-Method]]
- 비판: [[Anaemic-Domain-Model]] (Data Class)
- Adjacent: [[Architecture-Anti-Patterns]] · [[Quality_Code_Review_Modern]] · [[Clean-Code-Principles]] · [[SOLID]]
## 🤖 LLM 활용
**언제**: 매 code review. 매 refactor planning. 매 onboarding (smell 의 catalog 인지).
**언제 X**: 매 prototype (premature). 매 throwaway script.
## ❌ 안티패턴
- **모든 smell 의 fix 의 obsession**: 매 productivity ↓.
- **No measure**: 매 better 의 prove 의 X.
- **Smell 의 ignore**: 매 technical debt 의 accumulate.
- **Refactor without test**: 매 regression.
- **Big bang refactor**: 매 risky.
- **Clean Code 의 dogma**: 매 sometimes wrong.
## 🧪 검증 / 중복
- Verified (Fowler "Refactoring", Beck "Implementation Patterns", SonarQube rules).
- 신뢰도 A.
- Related: [[Architecture-Anti-Patterns]] · [[Anaemic-Domain-Model]] · [[Quality_Code_Review_Modern]] · [[Clean-Code-Principles]].
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — 6 category + refactor + 매 TS / Semgrep / SonarQube code |