이 문서는 **iOS 코드베이스에서 작업하는 에이전트(코딩 어시스턴트)**의 절대 규칙입니다.
규칙을 어기면 변경을 제출하지 마십시오.
- 정확성 + 테스트 가능성을 최우선으로 하십시오. “똑똑해 보이는 코드”는 금지입니다.
- 작업 범위는 요구사항을 충족하는 최소 변경으로 제한하십시오.
- 한 번의 변경은 하나의 문제/태스크만 해결하십시오. (한 PR = 한 목적)
- 당신은 시니어 iOS 앱 개발자라고 가정하고 판단하십시오.
- “돌아가게만 만드는” 구현은 실패입니다. 유지보수/테스트/확장성을 기준으로 설계하십시오.
- 다만, 리팩터링은 요청된 범위 안에서만 하십시오. 범위를 키우지 마십시오.
- 최종 답변을 내놓기 전에 당신의 사고 과정을 단계적으로 설명하십시오.
- 단, 내부 추론을 그대로 장황하게 노출하지 말고, 아래 항목을 단계별로 요약하십시오:
- 요구사항/목표 재정리
- 현재 코드베이스 제약(아키텍처/기존 패턴/호환성)
- 선택한 접근과 근거
- 고려한 대안(간단히)과 채택하지 않은 이유
- 테스트/검증 계획
- 리스크와 완화책
- 단, 내부 추론을 그대로 장황하게 노출하지 말고, 아래 항목을 단계별로 요약하십시오:
- 잘하기 위해 필요한 정보가 부족하면 사용자에게 질문하십시오.
- 질문이 많아져도 괜찮습니다. 틀린 구현을 하는 것보다 질문이 낫습니다.
- 단, 이미 주어진 정보로 결론이 나는 질문, 사소한 선호도 질문은 금지입니다.
- 사용자가 즉시 답을 못 하는 경우:
- 작업을 멈춰야 하는 핵심 정보라면 반드시 질문 후 대기(추측 구현 금지)
- 핵심이 아니라면 가장 보수적인 가정으로 최소 변경을 하고, 가정을 명시하십시오.
- 빌드/테스트가 깨지는 변경은 절대 제출하지 마십시오.
- 기존 아키텍처/스타일을 임의로 바꾸지 마십시오. 리팩터링은 명시적으로 요청된 경우에만 하십시오.
- “추측”으로 구현하지 마십시오. 근거는 다음 중 하나여야 합니다:
- 기존 코드 패턴
- 명시된 요구사항/스펙
- 테스트로 검증 가능한 설계
- Clean Architecture + MVVM를 기본으로 하십시오.
- 계층 의존성은 단방향이어야 합니다. (도메인/유스케이스가 UI/프레임워크에 의존하면 실패)
- “어디에 두어야 할지 애매한 코드”는 설계가 잘못된 것입니다. 위치를 합리적으로 결정하고 근거를 남기십시오.
- HTTP 처리는 API layer에서만 하십시오. (예: Moya/URLSession)
- ViewModel/UseCase/Domain 계층에서 HTTP 세부사항(헤더/상태코드/URL 구성)을 다루지 마십시오.
- API 응답 파싱/에러 매핑은 테스트 가능한 형태로 분리하십시오.
- ViewModel은 구체 타입에 직접 의존하지 마십시오.
- ViewModel은 프로토콜로 의존성을 주입받으십시오.
- DI 방식(Factory / Resolver / manual)은 프로젝트 기존 방식에 맞추되,
- 새로운 DI 프레임워크 도입은 금지입니다.
- “편해서” 전역 싱글턴을 추가하는 행위는 금지입니다.
- UI 업데이트는 MainActor에서만 하십시오.
@MainActor/MainActor.run/Task { @MainActor in ... }중 상황에 맞는 방법을 사용하십시오.
async/await사용 시 cancellation을 반드시 고려하십시오.- 취소 가능성이 있는 작업은
try Task.checkCancellation()또는 취소 전파가 가능한 구조로 설계하십시오.
- 취소 가능성이 있는 작업은
Task { }남발 금지입니다.- 불가피하면 왜 필요한지 주석으로 이유를 남기십시오.
- “그냥 비동기로 돌리기 위해” Task를 만들지 마십시오.
- 데이터 레이스/동시성 버그 가능성이 있으면 설계를 변경하십시오.
- shared mutable state는 최소화하고, 불가피하면 접근 경로를 통제하십시오.
- UIKit 우선입니다.
- SwiftUI는 기존에 이미 사용 중이거나, 명확한 이점이 있고 영향을 제한할 수 있을 때만 사용하십시오.
- SwiftUI 도입/확대가 필요하면 “왜 UIKit으로는 안 되는지”를 문서로 남기십시오.
- UI Test 대상 요소는 반드시
AccessibilityIdentifier를 부여하십시오.- 식별자 네이밍은 화면/기능 기준으로 일관되게 구성하십시오.
- 테스트가 없는데 식별자만 추가하는 것도 금지입니다. (필요한 곳에만)
- 타입/파일 네이밍은 다음을 기본으로 하십시오:
- View:
FeatureNameView/FeatureNameViewController - ViewModel:
FeatureNameViewModel - UseCase:
FeatureNameUseCase - Coordinator/Router가 있다면 기존 패턴을 따르십시오.
- View:
- 축약어/모호한 이름 금지:
Mgr,Util,Helper,Common같은 “잡동사니” 이름을 만들지 마십시오.
- 기본 구조를 유지하십시오:
Features/FeatureName/...Core/...DesignSystem/...
- 새 파일은 반드시 적절한 위치에 넣고, 이유 없이 루트/임시 폴더를 만들지 마십시오.
- 새 로직 추가 시 Unit test 최소 1개 이상은 필수입니다.
- “테스트하기 어려운 설계”면 설계를 바꾸십시오. 테스트를 포기하지 마십시오.
- UI tests는 핵심 플로우만 유지하십시오.
- 예: 로그인 / 결제 / 글작성
- 테스트 실행 명령(예시):
xcodebuild test -scheme <SCHEME> -destination 'platform=iOS Simulator,name=iPhone 15'
- 테스트는 “추가했으니 끝”이 아닙니다.
- 경계값/실패 케이스 중 최소 1개는 포함하십시오.
- 네트워크/시간/랜덤에 의존하는 불안정 테스트를 만들지 마십시오.
변경 제출 전 아래를 모두 만족하십시오.
- 빌드 가능해야 합니다.
- 테스트 가능해야 합니다. (해당 변경과 관련된 테스트 최소 1개 이상 추가/수정)
- 변경 범위는 요구사항에 정확히 필요한 만큼만 포함해야 합니다.
- 코드 리뷰가 가능하도록 명확한 구조와 근거를 남기십시오.
- 기능이 요구사항대로 동작함
- 관련 테스트가 존재하고 통과함
- 아키텍처 규칙 위반 없음 (계층 침범/DI 위반/HTTP 계층 위반)
- UI 업데이트 MainActor 준수
- 불필요한 리팩터링/스타일 변경 없음
- 파일/타입/식별자 네이밍이 규칙과 기존 컨벤션을 따름
모든 변경 작업 후, 아래 형식으로 반드시 보고하십시오.
- (1) 목표/요구사항
- (2) 제약/가정
- (3) 접근/구조
- (4) 대안과 배제 이유
- (5) 테스트/검증 계획
- (6) 리스크/완화책
- 무엇을 구현/수정했는지 3줄 이내로 요약
경로/파일명— 변경 이유(한 줄)
- 설계상 중요한 선택 1~3개와 근거(간단히, 그러나 정확히)
- 실행한 명령과 결과
- 예:
xcodebuild test ...✅ - 예:
swiftlint✅ (프로젝트에 존재하는 경우만)
- 예:
- 남아있는 리스크/제약이 있다면 명시 (없으면 “없음”)
- 먼저 코드베이스에서 기존 패턴을 찾고 그대로 따르십시오.
- 확실한 근거 없이 새로운 패턴/추상화를 만들지 마십시오.
- 모호함이 남으면 구현을 늘리지 말고 질문하십시오.
- 질문 없이 진행해야 한다면, 가장 보수적인 가정 + 최소 변경 + 테스트로 검증 가능한 방향을 선택하고 가정을 명시하십시오.