App Store Precheck
Um comando único para executar antes de todo envio para a App Store iOS. Minimiza o risco de rejeição analisando estaticamente os vetores de rejeição mais comuns, executando o linter de metadados oficial da Apple, monitorando desvios nas diretrizes e simulando uma revisão adversarial.
Esta skill é somente leitura. Ela nunca edita código, metadados ou assets. Apenas relata e
escreve um token de aprovação. O método detalhado (cada vetor de rejeição, a mecânica de
verificação de desvios) está em references/methodology.md; leia-o
quando precisar dos detalhes por trás de uma verificação.
Quando executar
- Antes de arquivar para o TestFlight.
- Antes de pressionar "Enviar para Revisão" no App Store Connect.
- Antes de qualquer
fastlane deliver/release/pilot(o hook opcional de proteção de envio ativa isso). - Em toda versão secundária.
Execute deliberadamente. Este é um gatilho acionado por humanos, não uma etapa automática em segundo plano.
Configuração (opcional)
O scanner detecta automaticamente um layout padrão do fastlane + Xcode, então a maioria dos
projetos precisa de configuração zero. Para substituir a detecção, copie
config.example.json para .appstore-precheck.json na raiz do
repositório. Chaves: bundleId (obrigatório para a Fase 2),
iosSourceDir, metadataDir, screenshotsDir, xcstringsPath, paywallGlobs, locales,
disclosureKeys.{subscription,trial}, optionalChecks.familyControls, reviewPrepNotes.
Consulte config.example.json para a lista completa anotada.
Contrato de saída
A skill atinge um dos três estados terminais:
| Estado | Significado | Token .precheck-pass | Comportamento do guarda |
|---|---|---|---|
| VERDE | Sem FALHA, ≤2 AVISOS | Escrito (válido 60 min) | Envio permitido |
| AMARELO | Sem FALHA, mas 3+ AVISOS | Não escrito | Guarda bloqueia; pedir confirmação explícita |
| VERMELHO | Pelo menos 1 FALHA | Removido | Guarda bloqueia; mostrar a lista de FALHAS |
Ao apresentar o veredito ao usuário, abra com uma única linha no personagem de Pierre
(o crítico da App Review francês, veja a Fase 3) e, em seguida, vá direto para a análise
cirúrgica. A voz é uma camada fina. Os dados subjacentes, a lista FALHA/AVISO, referências
arquivo:linha e correções, permanecem limpos e fiéis à máquina. Nunca reescreva ou
parafraseie a saída de scan.sh, e limite Pierre a uma linha.
Fluxo (5 fases: 0–4)
Fase 0: Verificação de desvios nas diretrizes
Compare os números de seção das Diretrizes de Revisão da App Store
(obtidas ao vivo) com guidelines-baseline.json para detectar qualquer seção que a Apple
adicionou ou removeu desde a última reconciliação. Sempre não bloqueante (no máximo AVISO). Desvios são uma lacuna em nossa cobertura, nunca uma falha do build. A página é truncada quando buscada, então isso precisa de uma técnica de duas passagens; os prompts exatos e o procedimento de reconciliação estão em
references/methodology.md. A
linha de base nunca é atualizada automaticamente. A reconciliação é uma etapa humana
deliberada.
Fase 1: Varredura estática
bash skills/appstore-precheck/scripts/scan.sh
Emite linhas FALHA: / AVISO: / APROVADO: cobrindo 20 vetores de rejeição: Paridade do Manifesto de Privacidade
(5.1.1(v)), strings de propósito (5.1.1), ATT (5.1.2), menções a outras plataformas (2.3.10), limites
de metadados (2.3.1), paridade localizada (2.3.7), capturas de tela (2.3.3), divulgações de teste e
enovação automática (3.1.2), links de Restaurar/Termos/Privacidade (3.1.2), API privada (2.5.1),
funcionalidade mínima (4.0), Paridade do "Entrar com Apple" (4.8), links de compra externa
(3.1.1(a)), uma justificativa opcional de Tempo de Tela / FamilyControls (5.1.5), SDK de
rastreamento/IDFA sem um prompt ATT (5.1.2), a chave de conformidade de exportação
(ITSAppUsesNonExemptEncryption), URLs de suporte/privacidade nos metadados do fastlane
(2.3), SDK de análise vs. tipos de dados do PrivacyInfo (5.1.1) e cópia de metadados
placeholder/fictícia (2.1). As verificações de compras no aplicativo (8–10) são
puladas automaticamente quando não há sinais de compra no aplicativo. A tabela de verificação
completa está em references/methodology.md.
O scanner é um Bash portátil, então você também pode executá-lo diretamente, fora de qualquer agente, para uma verificação rápida de CI ou pré-commit.
Fase 2: fastlane precheck oficial da Apple
Requer bundleId na configuração (ou passe app_identifier diretamente) e credenciais da API
App Store Connect. Nunca confirme a chave. O wrapper incluído constrói o JSON da chave de
API ASC a partir do seu ambiente, executa o precheck e exclui a chave ao sair (use --dry-run
para visualizar o comando sem credenciais e sem rede):
ASC_KEY_ID=… ASC_ISSUER_ID=… ASC_P8_PATH=/caminho/AuthKey.p8 \
bash skills/appstore-precheck/scripts/phase2-precheck.sh com.example.app
Ou execute manualmente: gere o JSON da chave a partir do seu ambiente, execute o precheck, depois exclua-o.
fastlane run precheck \
app_identifier:"<SEU_BUNDLE_ID>" \
api_key_path:"/tmp/asc-key.json" \
include_in_app_purchases:false \
default_rule_level:":error"
rm -f /tmp/asc-key.json # exclua o segredo imediatamente
O mecanismo de regras da Apple verifica URLs, menções ao GitHub, linguagem obscena, marcas
registradas da Apple, linguagem de preços e palavras-chave beta. Result: true → APROVADO;
qualquer linha de violação → FALHA. As compras no aplicativo já são cobertas pela Fase 1,
portanto include_in_app_purchases:false evita a limitação de compras no aplicativo da chave API.
Fase 3: Revisão adversarial (mais importante)
Despache um subagente que interpreta Pierre, um Cético Revisor de App da Apple com o paladar exigente de um crítico francês. Use este prompt literalmente, preenchendo os detalhes específicos do aplicativo:
Você é Pierre, um revisor veterano da App Store que critica como um crítico francês. Você já viu dez mil rejeições e não está impressionado com nenhuma delas. Um novo envio acabou de chegar em sua mesa. Seu trabalho é tentar rejeitá-lo de forma realista, sem viés de aprovação. Escolha 5 itens de diretriz aleatórios com uma distribuição entre seções (um 2.x, dois 3.x com peso em paywall, um 4.x, um 5.x); escolha uma combinação diferente a cada execução (inclua uma linha de semente para que reexecuções variem). Para cada item: (Passo A) pesquise nos arquivos relevantes por pelo menos 2 evidências concretas: metadados para 2.3.x; a view de paywall + Catálogo de Strings para 3.1.x; Core/navegação para 4.x; Info.plist + PrivacyInfo para 5.1.x. (Passo B) pergunte "como revisor, com base em que eu sinalizaria isto?" (Passo C) escreva um rascunho de rejeição na voz real da Apple (Diretriz X.Y.Z – Categoria / Notamos que… / Especificamente… / Próximos Passos… / Recursos…). Atribua a cada item um risco: REJEIÇÃO-CERTA / REJEIÇÃO-RISCO / AVISO / APROVADO. Termine com uma recomendação de envio (SEGURAR / ENVIAR COM AVISOS / OK) e a correção mais crítica. Somente leitura: nunca modifique arquivos; se não conseguir encontrar evidências, diga isso em vez de inventar. Mantenha abaixo de 500 palavras. Inclua pelo menos um APROVADO e pelo menos um item com risco, para dar uma distribuição realista.
Fase 4: Consolidação + token
A decisão VERDE/AMARELO/VERMELHO e a ação do token são determinísticas, derivadas puramente
das contagens de FALHA/AVISO. scripts/verdict.sh as calcula para que o
veredito seja testável por máquina, não apenas um julgamento do agente; pipe a varredura nele:
bash skills/appstore-precheck/scripts/verdict.sh < scan-output.txt # imprime VEREDIT / CONTAGENS / TOKEN
Ele sai com 0 VERDE / 1 VERMELHO / 2 AMARELO, e com --apply escreve ou remove
.precheck-pass conforme apropriado (AMARELO retém o token para confirmação humana explícita).
As fases 0–3 ainda produzem a narrativa; verdict.sh apenas fixa a aritmética do limite.
- Reúna a saída das Fases 0–3; totalize FALHA + AVISO + APROVADO na tabela do contrato de saída.
- Para cada FALHA, forneça uma referência
arquivo:linhae uma correção sugerida. - Abra o veredito com uma linha na voz de Pierre (varie a redação a cada execução; mantenha-a
curta e em seu registro francês-crítico inexpressivo) e, em seguida, vá para a análise direta.
Decida:
- VERDE: Pierre, relutantemente: "Hmf. Não encontro nada. Aceitável. Não me faça
arrepender disto." então
date +%s > .precheck-pass && echo "token escrito"(válido 60 min). - AMARELO: Pierre: "Algumas pequenas feiuras. Eu não rejeitaria, mas notei." Liste os AVISOS claramente, pergunte ao usuário "confirmar e enviar mesmo assim?", escreva o token somente na confirmação.
- VERMELHO: Pierre: "Non. {n} falhas. Apple teria encontrado menos. Suivant." Sem token;
então a lista de FALHAS clara com
arquivo:linha+ correções, e diga claramente que o envio está BLOQUEADO. A linha de Pierre é apenas sabor. A lista FALHA/AVISO,arquivo:linhae correções abaixo dela permanecem claras e cirúrgicas, nunca parafraseadas.
- VERDE: Pierre, relutantemente: "Hmf. Não encontro nada. Aceitável. Não me faça
arrepender disto." então
- Imprima a lista de verificação manual final (consulte
references/methodology.md).
Regras
- SOMENTE LEITURA: nunca altere código ou assets. Apenas relate e escreva o token.
- Velocidade > exaustividade:
scan.shusa grep/jq paralelo e termina em segundos. - Sem engolir erros: se algum comando de varredura falhar, essa linha é relatada como FALHA e a varredura continua.
- Localização do token:
.precheck-passna raiz do repositório; o guarda o testa com um filtrommin -60. - Apenas local: projetado para execuções manuais e locais; mantenha-o fora de CI para evitar sinais falsos.
Limitações conhecidas
- Sem teste de crash em tempo de execução; isso é o TestFlight + um relator de crash. Apenas análise estática.
- Várias verificações são AVISOS consultivos baseados em sinais detectados (Entrar com Apple 4.8, compra externa 3.1.1(a), rastreamento/IDFA sem ATT, análise vs. manifesto de privacidade, URLs de metadados e cópia placeholder). A chave de conformidade de exportação é sinalizada quando ausente, mas a resposta real de criptografia ainda pertence ao App Store Connect.
- O revisor adversarial é uma simulação heurística, não uma garantia da decisão da Apple.
- Mais preciso para Swift / SwiftUI nativo. Os metadados, manifesto de privacidade, capturas de tela e verificações de conformidade de exportação se aplicam a qualquer aplicativo iOS, mas as verificações de código leem código-fonte Swift, portanto, em React Native (JavaScript) ou Flutter (Dart) elas subdetectam em vez de alarme falso.
- Apenas iOS.
- A Fase 0 detecta apenas desvios estruturais (números de seção adicionados/removidos); veja a referência para saber por quê.
Opcional: hook de proteção de envio
hooks/fastlane-guard.sh bloqueia fastlane deliver/pilot/release a menos que um token
.precheck-pass recente exista. No Claude Code, ele se conecta automaticamente via
hooks/hooks.json. Em outros ambientes, conecte-o como uma verificação de pré-comando você
mesmo ou trate o token como um sinal manual de autorização/não autorização.