Communitygithub.com

berkayturk/appstore-precheck

읽기 전용 iOS App Store 사전 제출 점검: 20가지 거절 벡터를 스캔하고, Apple의 fastlane precheck를 래핑하며, 가이드라인 변경을 감시하고, 제출 전에 적대적 검토를 실행합니다.

appstore-precheck란 무엇인가요?

이 스킬은 iOS 앱을 App Store에 제출하기 전에 실행하는 원스톱 게이트입니다. 20가지 일반적인 거절 사유를 정적으로 스캔하고, Apple의 공식 fastlane precheck를 통합하며, Apple의 실시간 검토 가이드라인 변경을 감지하고, Pierre라는 프랑스 비평가 스타일의 적대적 검토관을 시뮬레이션합니다. Claude Code, Cursor, Codex 등 모든 AI 에이전트와 함께 사용할 수 있으며, Bash 기반 스캐너는 에이전트 외부에서 직접 실행하여 CI 또는 pre-commit 훅으로 사용할 수도 있습니다. 이 스킬은 읽기 전용으로, 코드나 메타데이터를 절대 수정하지 않고 결과만 보고하며, 합격/경고/불합격 상태에 따라 .precheck-pass 토큰을 생성합니다. 이를 통해 개발자는 제출 전에 잠재적 문제를 사전에 파악하고 수정하여 앱 거절 위험을 크게 줄일 수 있습니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add berkayturk/appstore-precheck

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

App Store Precheck

모든 iOS App Store 제출 전에 실행하는 원스톱 명령어입니다. 일반적인 거절 벡터를 정적으로 스캔하고, Apple의 공식 메타데이터 린터를 실행하며, 가이드라인 변경을 감시하고, 적대적 검토 프로세스를 시뮬레이션하여 거절 위험을 최소화합니다.

이 스킬은 읽기 전용입니다. 코드, 메타데이터, 에셋을 절대 수정하지 않습니다. 결과를 보고하고 패스 토큰만 기록합니다. 상세 방법(각 거절 벡터, 변경 감지 메커니즘)은 references/methodology.md에 있습니다. 특정 검사에 대한 세부 정보가 필요할 때 참조하세요.

실행 시점

  • TestFlight 아카이브 전.
  • App Store Connect에서 "검토 제출" 버튼을 누르기 전.
  • fastlane deliver / release / pilot 실행 전 (선택적 업로드 가드 훅이 이를 제어합니다).
  • 모든 포인트 릴리스 시.

의도적으로 실행하세요. 이는 사람이 트리거하는 게이트이며, 자동 백그라운드 단계가 아닙니다.

설정 (선택 사항)

스캐너는 표준 fastlane + Xcode 레이아웃을 자동 감지하므로 대부분의 프로젝트에서 설정이 필요 없습니다. 감지를 재정의하려면 config.example.json을 리포지토리 루트에 .appstore-precheck.json으로 복사하세요. 키: bundleId (2단계 필수), iosSourceDir, metadataDir, screenshotsDir, xcstringsPath, paywallGlobs, locales, disclosureKeys.{subscription,trial}, optionalChecks.familyControls, reviewPrepNotes. 전체 주석 목록은 config.example.json을 참조하세요.

출력 계약

이 스킬은 세 가지 종료 상태 중 하나에 도달합니다:

상태의미.precheck-pass 토큰가드 동작
GREENFAIL 없음, WARN ≤2개기록됨 (60분 유효)업로드 허용
YELLOWFAIL 없지만 WARN 3개 이상기록 안 됨가드가 차단하고 명시적 확인 요청
REDFAIL 1개 이상제거됨가드가 차단하고 FAIL 목록 표시

사용자에게 결과를 제시할 때는 Pierre(Pierre) (3단계 참조)의 단일 인격체 한 줄로 시작한 후 바로 일반적이고 정확한 분석으로 전환하세요. 목소리는 얇은 래퍼일 뿐입니다. 그 아래의 데이터(FAIL/WARN 목록, file:line 참조, 수정 사항)는 깨끗하고 기계에 충실하게 유지됩니다. 절대 scan.sh 출력을 다시 쓰거나 의역하지 말고, Pierre는 한 줄로 제한하세요.

흐름 (5단계: 0–4)

0단계: 실시간 가이드라인 변경 확인

실시간 App Store 검토 가이드라인 섹션 번호를 guidelines-baseline.json과 비교하여 Apple이 마지막 조정 이후 추가 또는 제거한 섹션을 감지합니다. 항상 비차단(WARN 최대). 변경은 우리 적용 범위의 차이이며, 빌드의 잘못이 아닙니다. 페이지를 가져올 때 잘리므로 두 번 패스하는 기술이 필요합니다. 정확한 프롬프트와 조정 절차는 references/methodology.md에 있습니다. 기준선은 절대 자동 업데이트되지 않습니다. 조정은 의도적인 사람의 단계입니다.

1단계: 정적 스캔

bash skills/appstore-precheck/scripts/scan.sh

20가지 거절 벡터를 포괄하는 FAIL: / WARN: / PASS: 줄을 출력합니다: 개인정보 보호 매니페스트 일치(5.1.1(v)), 목적 문자열(5.1.1), ATT(5.1.2), 다른 플랫폼 언급(2.3.10), 메타데이터 제한(2.3.1), 현지화 일치(2.3.7), 스크린샷(2.3.3), 평가판 및 자동 갱신 공개(3.1.2), 복원/약관/개인정보 링크(3.1.2), 비공개 API(2.5.1), 최소 기능(4.0), Apple로 로그인 일치(4.8), 외부 구매 링크(3.1.1(a)), 옵트인 Screen Time / FamilyControls 근거(5.1.5), ATT 프롬프트 없는 추적/IDFA SDK(5.1.2), 수출 컴플라이언스 키(ITSAppUsesNonExemptEncryption), fastlane 메타데이터의 지원/개인정보 URL(2.3), 분석 SDK 대 PrivacyInfo 데이터 유형(5.1.1), 플레이스홀더/더미 메타데이터 복사(2.1). IAP 검사(8-10)는 인앱 구매 신호가 없을 때 자동으로 건너뜁니다. 전체 검사 표는 references/methodology.md에 있습니다.

스캐너는 이식 가능한 Bash이므로 에이전트 외부에서 직접 실행하여 빠른 CI 또는 pre-commit 검사로도 사용할 수 있습니다.

2단계: Apple의 공식 fastlane precheck

설정에 bundleId가 필요하고(또는 app_identifier 직접 전달) App Store Connect API 자격 증명이 필요합니다. 키를 절대 커밋하지 마세요. 번들로 제공되는 래퍼는 환경에서 ASC API 키 JSON을 빌드하고, precheck를 실행하며, 종료 시 키를 삭제합니다(--dry-run을 사용하면 자격 증명 없이 명령어 미리보기 가능):

ASC_KEY_ID=… ASC_ISSUER_ID=… ASC_P8_PATH=/path/AuthKey.p8 \
  bash skills/appstore-precheck/scripts/phase2-precheck.sh com.example.app

또는 수동으로 실행: 환경에서 키 JSON을 생성하고, precheck를 실행한 다음 삭제합니다.

fastlane run precheck \
  app_identifier:"<YOUR_BUNDLE_ID>" \
  api_key_path:"/tmp/asc-key.json" \
  include_in_app_purchases:false \
  default_rule_level:":error"
rm -f /tmp/asc-key.json   # 즉시 비밀 삭제

Apple의 자체 규칙 엔진은 URL, GitHub 언급, 욕설, Apple 상표, 가격 언어, 베타 키워드를 검사합니다. Result: true → PASS; 위반 줄이 있으면 → FAIL. IAP는 이미 1단계에서 다루므로 include_in_app_purchases:false는 API 키 IAP 제한을 피합니다.

3단계: 적대적 검토 (가장 중요)

**Pierre(Pierre)**라는, 프랑스 비평가의 까다로운 취향을 가진 회의적인 Apple 앱 검토관 역할을 하는 하위 에이전트를 파견합니다. 이 프롬프트를 그대로 사용하고 앱의 세부 정보를 채우세요:

당신은 Pierre입니다. 프랑스 비평가처럼 비판하는 베테랑 Apple 앱 검토관입니다. 수천 건의 거절을 보았고 그 어느 것도 인상적이지 않습니다. 새로운 제출물이 방금 당신의 책상에 도착했습니다. 당신의 임무는 승인 편향 없이 현실적으로 거절을 시도하는 것입니다. 섹션 전체에 분산된 5개의 무작위 가이드라인 항목을 선택하세요(2.x 하나, 3.x 두 개(페이월에 가중치), 4.x 하나, 5.x 하나). 실행할 때마다 다른 조합을 선택하세요(재실행 시 변동을 위해 시드 라인 포함). 각 항목: (패스 A) 관련 파일을 grep하여 최소 2개의 구체적인 증거(2.3.x의 경우 메타데이터; 3.1.x의 경우 페이월 뷰 + 문자열 카탈로그; 4.x의 경우 Core/탐색; 5.1.x의 경우 Info.plist + PrivacyInfo)를 찾습니다. (패스 B) "검토관으로서, 무엇을 근거로 이 항목을 지적하겠습니까?"라고 물어보세요. (패스 C) Apple의 실제 어조(Guideline X.Y.Z – Category / We noticed… / Specifically… / Next Steps… / Resources…)로 거절 초안을 작성하세요. 각 항목에 위험 등급을 지정하세요: REJECT-CERTAIN / REJECT-RISK / WARN / PASS. 마지막에 제출 권장 사항(HOLD / SUBMIT WITH WARNINGS / GO)과 가장 중요한 단일 수정 사항을 제시하세요. 읽기 전용: 파일을 절대 수정하지 마세요. 증거를 찾을 수 없으면 증거를 발명하지 말고 그렇게 말하세요. 500단어 미만으로 유지하세요. 현실적인 분포를 위해 최소 하나의 PASS와 하나의 위험 항목을 포함하세요.

4단계: 통합 + 토큰

GREEN/YELLOW/RED 결정 및 토큰 동작은 결정론적이며, FAIL/WARN 개수에서만 파생됩니다. scripts/verdict.sh가 이를 계산하여 결과가 단순한 에이전트 판단이 아닌 기계 테스트 가능하도록 합니다. 스캔 결과를 이 스크립트로 파이프하세요:

bash skills/appstore-precheck/scripts/verdict.sh < scan-output.txt   # VERDICT / COUNTS / TOKEN 출력

종료 코드: 0 GREEN / 1 RED / 2 YELLOW이며, --apply와 함께 사용하면 .precheck-pass를 쓰거나 제거합니다(YELLOW는 명시적 사람 확인을 위해 토큰을 보류). 0-3단계는 여전히 설명을 생성합니다. verdict.sh는 임계값 산술만 고정합니다.

  1. 0-3단계 출력을 수집합니다. FAIL + WARN + PASS를 출력 계약 테이블로 집계합니다.
  2. 각 FAIL에 대해 file:line 참조와 제안된 수정 사항을 제공합니다.
  3. 결과를 Pierre의 목소리로 한 줄로 열고(실행할 때마다 표현을 바꾸고, 그의 무표정한 프랑스 비평가 어조를 유지하며 짧게 유지), 그런 다음 일반 분석으로 전환합니다. 결정:
    • GREEN: Pierre, 마지못해: "흠. 아무것도 찾지 못했군. 받아들일 만해. 후회하게 만들지 마." 그런 다음 date +%s > .precheck-pass && echo "token written" (60분 유효).
    • YELLOW: Pierre: "몇 개 작은 흠이 있군. 거절할 정도는 아니지만, 눈에 띄었어." WARN을 간결하게 나열하고 "확인하고 그래도 제출하시겠습니까?"라고 물어본 후 확인 시에만 토큰을 기록합니다.
    • RED: Pierre: "안 돼. {n}개의 결함. Apple이 찾는 것보다 적지만, 다음." 토큰 없음. 그런 다음 file:line + 수정 사항이 포함된 일반 FAIL 목록과 제출이 차단되었음을 명확히 알립니다. Pierre 줄은 장식일 뿐입니다. 그 아래의 FAIL/WARN 목록, file:line 및 수정 사항은 평이하고 정확하게 유지되며 의역하지 않습니다.
  4. 최종 수동 체크리스트를 출력합니다(references/methodology.md 참조).

규칙

  • 읽기 전용: 코드나 에셋을 절대 변경하지 마세요. 보고하고 토큰만 기록합니다.
  • 속도 > 완전성: scan.sh는 병렬 grep/jq를 사용하며 수 초 내에 완료됩니다.
  • 오류 무시 금지: 스캔 명령이 실패하면 해당 줄은 FAIL로 보고되고 스캔은 계속됩니다.
  • 토큰 위치: 리포지토리 루트의 .precheck-pass; 가드는 mmin -60 필터로 테스트합니다.
  • 로컬 전용: 수동 로컬 실행용으로 설계되었습니다. 잘못된 신호를 방지하려면 CI에서 사용하지 마세요.

알려진 제한 사항

  • 런타임 크래시 테스트는 없습니다. 이는 TestFlight + 크래시 리포터가 담당합니다. 정적 분석만 수행합니다.
  • 여러 검사는 감지된 신호에 따라 조언적 WARN입니다 (Apple로 로그인 4.8, 외부 구매 3.1.1(a), ATT 없는 추적/IDFA, 분석 대 개인정보 매니페스트, 메타데이터 URL 및 플레이스홀더 복사). 수출 컴플라이언스 키는 없을 때 플래그가 지정되지만 실제 암호화 답변은 여전히 App Store Connect에 속합니다.
  • 적대적 검토자는 경험적 시뮬레이션이며 Apple의 결정을 보장하지 않습니다.
  • 기본 Swift / SwiftUI에서 가장 정확합니다. 메타데이터, 개인정보 매니페스트, 스크린샷 및 수출 컴플라이언스 검사는 모든 iOS 앱에 적용되지만 코드 수준 검사는 Swift 소스를 읽으므로 React Native(JavaScript) 또는 Flutter(Dart)에서는 오탐보다는 미탐이 더 많습니다.
  • iOS 전용입니다.
  • 0단계는 구조적 변경(추가/제거된 섹션 번호)만 감지합니다. 자세한 내용은 참조 문서를 확인하세요.

선택 사항: 업로드 가드 훅

hooks/fastlane-guard.sh는 유효한 .precheck-pass 토큰이 없으면 fastlane deliver/pilot/release를 차단합니다. Claude Code에서는 hooks/hooks.json을 통해 자동 연결됩니다. 다른 환경에서는 직접 pre-command 검사로 연결하거나 토큰을 수동 GO/NO-GO 신호로 처리하세요.

관련 스킬