모든 PR 은 변경된 패키지 범위에서 unit + widget + integration 테스트가 PASS 한 뒤에만 생성될 수 있다. 이 문서는 구속력 있는 정책 이며, 스킬/커맨드/훅이 모두 이를 준수한다.
1. 원칙#
- 모든 PR 은
/pr:preflightPASS 필수 — 자동(/dev:run) 또는 수동 실행 - Unit + Widget 레이어는 항상 실행 — skip 금지
-
Integration 레이어는 조건부 실행 가능
- 로컬:
@smoke또는 명시 요청 - CI: 전량
- 로컬:
- 변경된 패키지만 대상 — 전체 레포 강제 실행 금지 (속도 저하)
- Skip 사용은 감사 기록 —
.claude/preflight-skip.log
2. 레이어별 실행 정책#
| 레이어 | 로컬 | CI | Skip 정책 |
|---|---|---|---|
| Unit | ✅ 필수 | ✅ 전량 | 절대 불가 |
| Widget | ✅ 필수 | ✅ 전량 | 절대 불가 |
Integration (@smoke) |
⚠️ 권장 (디바이스 있을 때) | ✅ 필수 | 디바이스 없음 시 자동 skip |
| Integration (full) | ⚠️ 선택 (--with-integration=full) |
✅ 필수 | 로컬 skip 허용 |
3. 변경 패키지 감지 규칙#
포함 대상#
feature/*/— feature 모듈app/*/— 앱 패키지package/*/— 공용 패키지 (단, 테스트 파일 있을 때만)backend/*/— 서버팟 패키지 (serverpod-test-agent위임 범위)
부수 변경 (단독이면 scope 미추가)#
-
**/*.g.dart,**/*.freezed.dart,**/*.gr.dart,**/*.config.dart,**/*.gen.dart,**/*.mocks.dart -
**/*.widget_test.dart,**/*.patrol_test.dart(bdd_test_gen산출물)
제외 대상#
shared/*/중 순수 설정 —--include-shared없으면 제외-
docs/,*.md,.github/,.claude/,.cursor/,README.md,CHANGELOG.md i18n/*.json(언어 리소스만 변경 시 테스트 불필요, 다만.dart생성물 변경 시는 포함)
4. Skip 예외 규정#
정책상 거부 옵션#
--skip-unit→ 항상 거부 (exit code 2)--skip-widget→ 항상 거부 (exit code 2)
조건부 허용#
--skip-integration→ 로컬 기본값 (감사 기록 불필요)-
--skip-all→ hotfix 전용, 다음 조건 모두 만족--reason사유 명시- 커밋 메시지에
hotfix:,fix!:,revert:접두사 중 하나 - 감사 로그 기록
감사 로그 포맷 (.claude/preflight-skip.log)#
2026-04-23T12:34:56Z | user=dongwoo | branch=hotfix/payment-crash | base=development | skip=all | reason= " 프로덕션 결제 크래시 응급 패치 "
- 이 파일은 커밋 대상 (감사 추적)
- CI 가 파일 존재 시 강한 게이트로 대체 실행 (전량 unit + widget + integration)
5. /dev:run 과의 통합#
/dev:run 의 Step 8 (테스트 작성 및 검증) 은 본 정책의 구현체:
Step 8: 테스트 작성 및 검증 (필수 게이트) ⚠️
├── [테스트 코드 작성] ← cc-flutter-dev:test 에이전트
├── [PR Preflight 실행] ← /pr:preflight --auto-scope
│ ├── Unit (변경 패키지)
│ ├── Widget (변경 패키지)
│ └── Integration @smoke (조건부)
└── ⚠️ 실패 시 Step 9 (PR 생성) 진행 불가
/dev:run --skip-tests 는 본 정책의 --skip-all 과 동일하게 취급 (사유 필수).
6. lefthook 훅 통합 (프로젝트 레포)#
프로젝트 lefthook.yml 의 pre-push 에 권장 블록:
pre-push:
parallel: false
commands:
# 기존: format-check, analyze
# 추가: preflight (unit + widget 만 — integration 은 /pr:preflight 로 수동)
preflight-fast:
tags: test
run: |
if [ " $LEFTHOOK_SKIP_PREFLIGHT " = " 1 " ]; then
echo " ⚠️ LEFTHOOK_SKIP_PREFLIGHT=1 감지 — preflight 건너뜀 "
exit 0
fi
# 환경에 claude-code-cli 가 있으면 /pr:preflight, 없으면 melos 직접
if command -v claude-code-cli > /dev/null; then
claude-code-cli run /pr:preflight --from-hook --skip-integration
else
# 폴백
BASE=$(git rev-parse --abbrev-ref ' @{u} ' 2 > /dev/null | sed ' s|.*/|| ' )
BASE=${BASE:-development}
CHANGED=$(git diff --name-only " $BASE " ..HEAD | grep -E ' ^(feature|app|package|backend)/ ' | cut -d/ -f1-3 | sort -u)
if [ -n " $CHANGED " ]; then
# pubspec.yaml name 추출 후 melos scope 실행
melos run test --scope= " ... "
fi
fi
주의: integration 은 hook 에 두지 않음 (push 속도 저하). 개발자가 /pr:preflight --with-integration
명시 실행.
7. CI 연계#
CI 워크플로우 요구사항:
- PR 트리거 시 전량 unit + widget + integration 실행 (변경 패키지 한정 아님 — CI 는 방어선)
-
.claude/preflight-skip.log최근 엔트리 감지 시 강한 게이트:- 전체 레포 unit + widget + integration 실행
- 실패 시 머지 차단
- Nightly 는 skip 로그 무시하고 전량 실행
예시 .github/workflows/preflight-gate.yml:
name: preflight-gate
on:
pull_request:
branches: [development, main]
jobs:
unit-widget:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
- run: melos bootstrap
- run: melos run test
integration-smoke:
runs-on: macos-latest
steps:
# Patrol 시뮬레이터 실행
8. 실패 시 조치#
Unit FAIL#
flutter test <실패 파일>재실행cc-flutter-dev:test에이전트 위임- 수정 → 재커밋 →
/pr:preflight재실행
Widget FAIL (BDD widget_test 포함)#
-
bdd_test_gen최신 확인:dart run build_runner build --delete-conflicting-outputs - TestDriver step 검토: K 상수 적용 여부
- Mock 설정 재검토
Integration FAIL (Patrol)#
patrol develop+patrol_mcp run/screenshot/native-tree로 원인 분석cc-e2e-authoring:step-implement재진입- staging 서버 상태 확인 (네트워크/데이터 의존)
9. 금지 사항#
- ❌ Unit/Widget skip 허용
- ❌ 전체 레포 전량 실행 기본화 (
--full은 명시 요청 시만) - ❌ 감사 로그(
preflight-skip.log)를.gitignore - ❌ hook 안에서 integration 자동 실행 (push 속도 저하)
- ❌ 변경 없는 패키지를 scope 에 포함
10. 관련 문서#
- 스킬 본체:
cc-dev-cycle/skills/pr/SKILL.md - 커맨드:
cc-dev-cycle/commands/pr/preflight.md - 개발 사이클:
cc-dev-cycle/commands/dev/run.md(Step 8) - E2E 저작:
cc-e2e-authoring/skills/feature-test-bundle,scenario-lock -
테스트 표준:
cc-uiux/skills/unit-testing/SKILL.mdcc-uiux/skills/widget-testing/SKILL.mdcc-uiux/skills/bdd-testing/SKILL.mdcc-uiux/skills/integration-testing/SKILL.mdcc-flutter-dev/rules/bdd-test-patterns.md