App Store 事前チェック は何をしますか?
すべての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 を参照してください。
出力契約
スキルは以下の3つの終了状態のいずれかに達します。
| 状態 | 意味 | .precheck-pass トークン | ガードの動作 |
|---|---|---|---|
| GREEN | FAILなし、WARN 2件以下 | 書き込み(有効60分) | アップロード許可 |
| YELLOW | FAILなし、WARN 3件以上 | 書き込みなし | ガードがブロック。明示的な確認を要求 |
| RED | 少なくとも1件のFAIL | 削除 | ガードがブロック。FAILリストを表示 |
ユーザーに判定を提示するときは、Pierre(ピエール)の1行のキャラクターセリフ(フランス人App Review批評家、フェーズ3参照)で始め、その後すぐにプレーンで精密な分析結果に移ってください。この声は薄いラッパーです。その下にあるデータ、FAIL/WARNリスト、file:line 参照、修正方法は、クリーンで機械的に忠実に保ちます。scan.sh の出力を書き換えたり言い換えたりせず、Pierreのセリフは1行に留めてください。
フロー(5フェーズ:0~4)
フェーズ0:ライブガイドライン変更チェック
ライブの App Store レビューガイドライン のセクション番号を guidelines-baseline.json と比較し、最後の調整以降にAppleが追加または削除したセクションを検出します。常に非ブロッキング(最大でもWARN)。 変更は私たちのカバレッジのギャップであり、決してビルドの欠陥ではありません。ページは取得時に切り詰められるため、2パス手法が必要です。正確なプロンプトと調整手順は 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))、オプトインのスクリーンタイム/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、フランス人批評家の厳格な味覚を持つ懐疑的なApple Appレビュアーのロールプレイを行います。以下のプロンプトをそのまま使用し、アプリの詳細を記入してください。
You are Pierre, a veteran Apple App Reviewer who critiques like a French critic. You have seen ten thousand rejections and are impressed by none of them. A new submission just landed on your desk. Your job is to realistically try to reject it, with no approval bias. Pick 5 random guideline items with a spread across sections (one 2.x, two 3.x weighted toward paywall, one 4.x, one 5.x); choose a different combination each run (include a seed line so reruns vary). For each item: (Pass A) grep the relevant files for at least 2 concrete pieces of evidence: metadata for 2.3.x; the paywall view + String Catalog for 3.1.x; Core/navigation for 4.x; Info.plist + PrivacyInfo for 5.1.x. (Pass B) ask "as a reviewer, on what basis would I flag this?" (Pass C) write a rejection draft in Apple's real voice (Guideline X.Y.Z – Category / We noticed… / Specifically… / Next Steps… / Resources…). Assign each item a risk: REJECT-CERTAIN / REJECT-RISK / WARN / PASS. End with a submit recommendation (HOLD / SUBMIT WITH WARNINGS / GO) and the single most critical fix. Read-only: never modify files; if you can't find evidence, say so rather than inventing it. Keep it under 500 words. Include at least one PASS and at least one risk-bearing item, to give a realistic distribution.
フェーズ4:統合+トークン
GREEN/YELLOW/REDの判定とトークンアクションは決定論的であり、FAIL/WARNのカウントのみから導き出されます。scripts/verdict.sh がこれらを計算するため、判定はエージェントの判断だけでなく、機械的にテスト可能です。スキャンの出力をパイプで渡します。
bash skills/appstore-precheck/scripts/verdict.sh < scan-output.txt # 出力: VERDICT / COUNTS / TOKEN
GREENで終了コード0、REDで1、YELLOWで2を返し、--apply を指定すると .precheck-pass を書き込みまたは削除します(YELLOWは明示的な人間の確認のためにトークンを保持します)。フェーズ0~3の結果は引き続き生成されますが、verdict.shは閾値の計算を固定します。
- フェーズ0~3の出力を収集し、FAIL + WARN + PASS を出力契約テーブルに集計します。
- 各FAILについて、
file:line参照と修正方法の提案を提供します。 - 判定を Pierreの1行 のセリフで始め(実行ごとに言い回しを変え、彼の無表情なフランス人批評家の口調で短く)、その後プレーンな分析結果に移ります。決定:
- GREEN: Pierre、渋々: "Hmf. I find nothing. Acceptable. Do not make me regret this." その後
date +%s > .precheck-pass && echo "token written"(60分有効)。 - YELLOW: Pierre: "A few small uglinesses. I would not reject, but I noticed." WARNを平易にリストし、ユーザーに「確認して送信しますか?」と尋ね、確認があった場合のみトークンを書き込みます。
- RED: Pierre: "Non. {n} faults. Apple would have found fewer. Suivant." トークンなし。その後
file:lineと修正を含むプレーンなFAILリスト、および送信がBLOCKEDされていることを明確に示します。 Pierreのセリフは風味付けのみです。その下のFAIL/WARNリスト、file:line、修正はプレーンで外科的であり、言い換えられません。
- GREEN: Pierre、渋々: "Hmf. I find nothing. Acceptable. Do not make me regret this." その後
- 最終手動チェックリストを表示します(
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 を介して自動的に配線されます。その他の環境では、事前コマンドチェックとして自分で配線するか、トークンを手動のゴー/ノーゴーシグナルとして扱ってください。