diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index da5048f7..2e297fa8 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -4,5 +4,17 @@
## 작업사항
- [x]
+## TDD 체크
+- [ ] failing test부터 시작했다
+- [ ] 최소 구현으로 Green을 만들었다
+- [ ] Refactor는 Green 이후에만 수행했다
+
+## Tidy First 체크
+- [ ] 구조 변경과 동작 변경을 분리했다
+- [ ] 구조 변경만 있는 커밋은 동작을 바꾸지 않았다
+
+## Test plan
+- [ ]
+
## UI
diff --git a/Projects/App/Support/Info.plist b/Projects/App/Support/Info.plist
index 3c1ebe4e..8d69284c 100644
--- a/Projects/App/Support/Info.plist
+++ b/Projects/App/Support/Info.plist
@@ -21,9 +21,9 @@
CFBundlePackageType
$(PRODUCT_BUNDLE_PACKAGE_TYPE)
CFBundleShortVersionString
- 2.4.0
+ 2.5.1
CFBundleVersion
- 99
+ 101
FirebaseAppDelegateProxyEnabled
ITSAppUsesNonExemptEncryption
diff --git a/Projects/Core/Sources/Steps/CompanyDetailPreviousViewType.swift b/Projects/Core/Sources/Steps/CompanyDetailPreviousViewType.swift
index bc883172..e3e3c098 100644
--- a/Projects/Core/Sources/Steps/CompanyDetailPreviousViewType.swift
+++ b/Projects/Core/Sources/Steps/CompanyDetailPreviousViewType.swift
@@ -1,4 +1,5 @@
public enum CompanyDetailPreviousViewType {
case searchCompany
case recruitmentDetail
+ case home
}
diff --git a/Projects/Presentation/Sources/CompanyDetail/CompanyDetailPreviousViewType.swift b/Projects/Presentation/Sources/CompanyDetail/CompanyDetailPreviousViewType.swift
deleted file mode 100644
index a5f247f6..00000000
--- a/Projects/Presentation/Sources/CompanyDetail/CompanyDetailPreviousViewType.swift
+++ /dev/null
@@ -1,7 +0,0 @@
-import Foundation
-
-public enum CompanyDetailPreviousViewType {
- case searchCompany
- case recruitmentDetail
- case home
-}
diff --git a/plan.md b/plan.md
new file mode 100644
index 00000000..e9303a07
--- /dev/null
+++ b/plan.md
@@ -0,0 +1,78 @@
+# TDD / Tidy First Plan
+
+이 저장소에서는 앞으로 모든 작업을 Kent Beck의 TDD / Tidy First 원칙으로 진행한다.
+`go` 라고 하면 이 문서를 현재 작업의 단일 실행 기준으로 사용한다.
+
+## Always Follow
+- 항상 **Red → Green → Refactor** 순서를 지킨다.
+- 한 번에 테스트 **하나만** 추가한다.
+- 테스트가 **실패하는 것을 먼저 확인**한 뒤에만 프로덕션 코드를 수정한다.
+- 테스트를 통과시키는 **최소한의 코드만** 작성한다.
+- **구조 변경(Structural change)** 과 **동작 변경(Behavioral change)** 을 같은 커밋에 섞지 않는다.
+- 구조 변경이 필요하면 **먼저 구조만** 바꾸고 테스트로 안전성을 확인한다.
+- 리팩터링은 **테스트가 모두 초록불일 때만** 수행한다.
+- 각 단계가 끝날 때마다 **관련 테스트를 다시 실행**한다.
+
+## Tidy First Rules
+
+### Structural Change
+다음은 구조 변경으로 취급한다.
+- 이름 변경
+- 파일 이동
+- 타입/메서드 추출
+- 중복 제거를 위한 재배치
+- 의존성 방향은 유지한 채 표현만 정리하는 변경
+
+구조 변경 단계에서는:
+- 동작을 바꾸지 않는다.
+- 가능한 한 작은 단위로 나눈다.
+- 변경 전/후 테스트 결과가 같아야 한다.
+- 커밋 메시지와 PR 설명에 구조 변경임을 드러낸다.
+
+### Behavioral Change
+다음은 동작 변경으로 취급한다.
+- 새로운 기능 추가
+- 분기/상태/화면 흐름 변경
+- 사용자에게 보이는 결과 변경
+- 버그 수정
+
+동작 변경 단계에서는:
+- 반드시 실패하는 테스트로 시작한다.
+- 테스트를 통과시키는 최소 구현만 한다.
+- 초록불 이후에만 구조를 개선한다.
+
+## `go` Execution Contract
+`go` 라고 하면 아래 순서로 정확히 수행한다.
+1. `Test Queue` 에서 체크되지 않은 첫 번째 항목을 찾는다.
+2. 해당 항목에 대한 테스트를 **하나만** 작성한다.
+3. 테스트가 실패하는지 확인한다. (**Red**)
+4. 테스트를 통과시키는 최소 구현만 추가한다. (**Green**)
+5. 모든 관련 테스트를 다시 실행한다.
+6. 구조 개선이 필요하면 별도 구조 변경으로만 정리한다. (**Refactor / Tidy First**)
+7. `Test Queue` 상태를 갱신한다.
+
+## Definition of Done for One Step
+하나의 `go` 단계는 아래 조건을 만족할 때만 끝난다.
+- 이번 단계에서 추가한 테스트가 존재한다.
+- 새 테스트가 처음에는 실패했다.
+- 현재는 테스트가 통과한다.
+- 구조 변경과 동작 변경의 경계가 설명 가능하다.
+- 다음에 진행할 테스트가 `Test Queue` 에 명확히 남아 있다.
+
+## Swift Rules
+- Swift에서는 의미가 분명한 타입/메서드 이름을 우선한다.
+- `mutate()` 는 비동기 가능, `reduce()` 는 순수 함수만 유지한다.
+- `Flow.rootViewController` 는 `init` 에서 resolve 한다.
+- 레이어 역방향 import 금지.
+- 모든 의존성은 Assembly를 통해 등록한다.
+
+## PR / Commit Rules
+- 한 PR 안에서도 구조 변경 커밋과 동작 변경 커밋을 분리한다.
+- PR 설명에는 아래를 포함한다.
+ - 어떤 테스트가 먼저 실패했는지
+ - 어떤 최소 구현으로 초록불을 만들었는지
+ - 어떤 구조 개선을 나중에 했는지
+- 테스트 없이 기능 코드를 먼저 넣는 변경은 허용하지 않는다.
+
+## Test Queue
+- [ ] 다음 기능 작업이 정해지면 첫 failing test 를 여기에 추가한다.