Communitygithub.com

berkayturk/appstore-precheck

Verificación previa de solo lectura para el envío a la App Store de iOS: escanea 20 vectores de rechazo, utiliza fastlane precheck de Apple, monitorea desviaciones en las directrices y ejecuta una revisión adversarial antes de enviar.

¿Qué es appstore-precheck?

Esta habilidad actúa como una compuerta de control previa al envío a la App Store, diseñada para desarrolladores de iOS que utilizan Claude Code, Cursor u otros agentes de IA. Escanea estáticamente 20 vectores comunes de rechazo (como manifiestos de privacidad, cadenas de propósito, metadatos, capturas de pantalla, enlaces a otras plataformas, y más), ejecuta el linter oficial de metadatos de Apple a través de `fastlane precheck`, monitorea cambios estructurales en las directrices de revisión de la App Store (guideline drift), y simula una revisión adversarial interpretando a un revisor de Apple escéptico llamado Pierre. Todo el proceso es de solo lectura: nunca modifica código, metadatos ni activos. Genera un token de aprobación (`.precheck-pass`) con validez de 60 minutos que puede ser utilizado por hooks opcionales para bloquear envíos con `fastlane`. La salida se clasifica en tres estados: VERDE (sin fallos, máximo 2 advertencias), AMARILLO (sin fallos pero 3+ advertencias) y ROJO (al menos 1 fallo). Es más preciso para aplicaciones Swift/SwiftUI nativas, aunque las verificaciones de metadatos, manifiesto de privacidad y capturas de pantalla funcionan para cualquier app de iOS. Se ejecuta deliberadamente por el usuario, no como paso automático de fondo.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add berkayturk/appstore-precheck

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

App Store Precheck

Un comando único para ejecutar antes de cada envío a la App Store de iOS. Minimiza el riesgo de rechazo escaneando estáticamente los vectores de rechazo más comunes, ejecutando el linter de metadatos oficial de Apple, monitoreando desviaciones en las directrices y simulando una revisión adversarial.

Esta habilidad es de solo lectura. Nunca edita código, metadatos ni recursos. Solo informa y escribe un token de aprobación. El método detallado (cada vector de rechazo, los mecanismos de verificación de desviación) se encuentra en references/methodology.md; léelo cuando necesites los detalles específicos detrás de una verificación.

Cuándo ejecutarlo

  • Antes de archivar para TestFlight.
  • Antes de presionar "Enviar para revisión" en App Store Connect.
  • Antes de cualquier fastlane deliver / release / pilot (el hook opcional de protección de envío lo controla).
  • En cada release menor.

Ejecútalo deliberadamente. Es una compuerta activada por humanos, no un paso automático de fondo.

Configuración (opcional)

El escáner detecta automáticamente una estructura estándar de fastlane + Xcode, por lo que la mayoría de los proyectos necesitan configuración cero. Para anular la detección, copia config.example.json a .appstore-precheck.json en la raíz del repositorio. Claves: bundleId (requerido para la Fase 2), iosSourceDir, metadataDir, screenshotsDir, xcstringsPath, paywallGlobs, locales, disclosureKeys.{subscription,trial}, optionalChecks.familyControls, reviewPrepNotes. Consulta config.example.json para la lista anotada completa.

Contrato de salida

La habilidad alcanza uno de tres estados terminales:

EstadoSignificadoToken .precheck-passComportamiento de la protección
VERDESin FALLO, ≤2 ADVERTENCIASEscrito (válido 60 min)Envío permitido
AMARILLOSin FALLO pero 3+ ADVERTENCIASNo escritoLa protección bloquea; pide confirmación explícita
ROJOAl menos 1 FALLOEliminadoLa protección bloquea; muestra la lista de FALLOS

Cuando presentes el veredicto al usuario, comienza con una sola línea en el personaje de Pierre (el crítico francés de revisión de la App Store, ver Fase 3), luego pasa directamente al desglose quirúrgico y sencillo. La voz es una capa delgada. Los datos subyacentes, la lista de FALLO/ADVERTENCIA, referencias archivo:línea y correcciones, se mantienen limpios y fieles a la máquina. Nunca reescribas ni parafrasees la salida de scan.sh, y limita a Pierre a una línea.

Flujo (5 fases: 0–4)

Fase 0: Verificación de desviación en directrices en vivo

Compara los números de sección de las Directrices de revisión de la App Store en vivo con guidelines-baseline.json para detectar cualquier sección que Apple haya añadido o eliminado desde la última reconciliación. Siempre no bloqueante (como máximo ADVERTENCIA). La desviación es una brecha en nuestra cobertura, nunca un error del build. La página se trunca al obtenerse, por lo que esto necesita una técnica de dos pasos; las indicaciones exactas y el procedimiento de reconciliación están en references/methodology.md. La línea base nunca se actualiza automáticamente. La reconciliación es un paso humano deliberado.

Fase 1: Escaneo estático

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

Emite líneas FALLO: / ADVERTENCIA: / APROBADO: que cubren 20 vectores de rechazo: Paridad del Manifiesto de Privacidad (5.1.1(v)), cadenas de propósito (5.1.1), ATT (5.1.2), menciones de otras plataformas (2.3.10), límites de metadatos (2.3.1), paridad localizada (2.3.7), capturas de pantalla (2.3.3), divulgaciones de prueba y renovación automática (3.1.2), enlaces de Restaurar/Términos/Privacidad (3.1.2), API privada (2.5.1), funcionalidad mínima (4.0), Iniciar sesión con Apple (4.8), enlaces de compra externa (3.1.1(a)), una justificación optativa de Screen Time / FamilyControls (5.1.5), SDK de seguimiento/IDFA sin un mensaje de ATT (5.1.2), la clave de cumplimiento de exportación (ITSAppUsesNonExemptEncryption), URLs de soporte/privacidad en metadatos de fastlane (2.3), SDK de análisis frente a tipos de datos de PrivacyInfo (5.1.1), y texto de metadatos placeholder/dummy (2.1). Las comprobaciones de IAP (8–10) se omiten automáticamente cuando no hay señales de compras dentro de la aplicación. La tabla de verificación completa está en references/methodology.md.

El escáner es Bash portátil, por lo que también puedes ejecutarlo directamente, fuera de cualquier agente, para una verificación rápida en CI o pre-commit.

Fase 2: fastlane precheck oficial de Apple

Requiere bundleId en la configuración (o pasar app_identifier directamente) y credenciales de la API de App Store Connect. Nunca subas la clave. El envoltorio incluido construye el JSON de la clave de API de ASC desde tu entorno, ejecuta precheck y elimina la clave al salir (usa --dry-run para previsualizar el comando sin credenciales ni red):

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

O ejecútalo manualmente: genera el JSON de la clave desde tu entorno, ejecuta precheck, luego elimínalo.

fastlane run precheck \
  app_identifier:"<TU_BUNDLE_ID>" \
  api_key_path:"/tmp/asc-key.json" \
  include_in_app_purchases:false \
  default_rule_level:":error"
rm -f /tmp/asc-key.json   # elimina el secreto inmediatamente

El motor de reglas propio de Apple verifica URLs, menciones de GitHub, lenguaje soez, marcas comerciales de Apple, lenguaje de precios y palabras clave beta. Result: true → APROBADO; cualquier línea de violación → FALLO. IAP ya está cubierto por la Fase 1, por lo que include_in_app_purchases:false evita la limitación de IAP de la clave API.

Fase 3: Revisión adversarial (la más importante)

Envía un subagente que interpreta a Pierre, un revisor escéptico de la App Store de Apple con el paladar exigente de un crítico francés. Usa esta indicación textualmente, completando los detalles de la aplicación:

Eres Pierre, un revisor veterano de la App Store de Apple que critica como un crítico francés. Has visto diez mil rechazos y ninguno te impresiona. Una nueva solicitud acaba de llegar a tu escritorio. Tu trabajo es intentar rechazarla de manera realista, sin sesgo de aprobación. Elige 5 elementos aleatorios de las directrices con una distribución entre secciones (una 2.x, dos 3.x con peso hacia paywall, una 4.x, una 5.x); elige una combinación diferente cada vez (incluye una línea semilla para que las repeticiones varíen). Para cada elemento: (Paso A) busca en los archivos relevantes al menos 2 piezas concretas de evidencia: metadatos para 2.3.x; la vista de paywall + Catálogo de cadenas para 3.1.x; Core/navegación para 4.x; Info.plist + PrivacyInfo para 5.1.x. (Paso B) pregunta "como revisor, ¿sobre qué base marcaría esto?" (Paso C) escribe un borrador de rechazo en la voz real de Apple (Directriz X.Y.Z – Categoría / Hemos notado… / Específicamente… / Próximos pasos… / Recursos…). Asigna a cada elemento un riesgo: RECHAZO-SEGURO / RECHAZO-RIESGO / ADVERTENCIA / APROBADO. Termina con una recomendación de envío (RETENER / ENVIAR CON ADVERTENCIAS / ADELANTE) y la única corrección más crítica. Solo lectura: nunca modifiques archivos; si no puedes encontrar evidencia, dilo en lugar de inventarla. Mantenlo por debajo de 500 palabras. Incluye al menos un APROBADO y al menos un elemento con riesgo, para dar una distribución realista.

Fase 4: Consolidación + token

La decisión VERDE/AMARILLO/ROJO y la acción del token son deterministas, derivadas puramente de los conteos de FALLO/ADVERTENCIA. scripts/verdict.sh los calcula para que el veredicto sea comprobable por máquina, no solo un juicio del agente; canaliza el escaneo hacia él:

bash skills/appstore-precheck/scripts/verdict.sh < salida-escaneo.txt   # imprime VEREDICTO / CONTEO / TOKEN

Sale con código 0 VERDE / 1 ROJO / 2 AMARILLO, y con --apply escribe o elimina .precheck-pass según corresponda (AMARILLO retiene el token para confirmación humana explícita). Las fases 0–3 aún producen la narrativa; verdict.sh simplemente fija la aritmética del umbral.

  1. Reúne la salida de las fases 0–3; cuenta FALLO + ADVERTENCIA + APROBADO en la tabla del contrato de salida.
  2. Para cada FALLO, da una referencia archivo:línea y una corrección sugerida.
  3. Abre el veredicto con una línea en la voz de Pierre (varía la redacción cada vez; mantenla corta y en su registro muerto de crítico francés), luego pasa al desglose sencillo. Decide:
    • VERDE: Pierre, a regañadientes: "Hmf. No encuentro nada. Aceptable. No me hagas arrepentir de esto." luego date +%s > .precheck-pass && echo "token escrito" (válido 60 min).
    • AMARILLO: Pierre: "Unas pequeñas fealdades. No rechazaría, pero lo noté." Enumera las ADVERTENCIAS claramente, pregunta al usuario "¿confirmar y enviar de todos modos?", escribe el token solo tras la confirmación.
    • ROJO: Pierre: "No. {n} fallos. Apple habría encontrado menos. Suivant." Sin token; luego la lista sencilla de FALLOS con archivo:línea + correcciones, y afirma claramente que el envío está BLOQUEADO. La línea de Pierre es solo sabor. La lista de FALLO/ADVERTENCIA, archivo:línea y correcciones debajo se mantienen sencillas y quirúrgicas, nunca parafraseadas.
  4. Imprime la lista de verificación manual final (consulta references/methodology.md).

Reglas

  • SOLO LECTURA: nunca cambiar código o recursos. Solo informar y escribir el token.
  • Velocidad > exhaustividad: scan.sh usa grep/jq en paralelo y termina en segundos.
  • Sin ocultar errores: si algún comando de escaneo falla, esa línea se reporta como FALLO y el escaneo continúa.
  • Ubicación del token: .precheck-pass en la raíz del repositorio; la protección lo prueba con un filtro mmin -60.
  • Solo local: diseñado para ejecuciones manuales y locales; mantenlo fuera de CI para evitar señales falsas.

Limitaciones conocidas

  • Sin pruebas de fallos en tiempo de ejecución; eso es TestFlight + un reportador de fallos. Solo análisis estático.
  • Varias comprobaciones son ADVERTENCIAS informativas controladas por señales detectadas (Iniciar sesión con Apple 4.8, compra externa 3.1.1(a), seguimiento/IDFA sin ATT, análisis frente a manifiesto de privacidad, URLs de metadatos y texto placeholder). La clave de cumplimiento de exportación se señala cuando está ausente, pero la respuesta de cifrado real aún pertenece a App Store Connect.
  • El revisor adversarial es una simulación heurística, no una garantía de la decisión de Apple.
  • Más preciso para Swift / SwiftUI nativo. Las comprobaciones de metadatos, manifiesto de privacidad, capturas de pantalla y cumplimiento de exportación aplican a cualquier app de iOS, pero las comprobaciones a nivel de código leen código fuente Swift, por lo que en React Native (JavaScript) o Flutter (Dart) subdetectan en lugar de dar falsos positivos.
  • Solo iOS.
  • La Fase 0 detecta solo desviaciones estructurales (números de sección añadidos/eliminados); consulta la referencia para saber por qué.

Opcional: hook de protección de envío

hooks/fastlane-guard.sh bloquea fastlane deliver/pilot/release a menos que exista un token .precheck-pass fresco. En Claude Code se conecta automáticamente a través de hooks/hooks.json. En otros entornos, conéctalo tú mismo como una comprobación previa al comando, o trata el token como una señal manual de proceder/no proceder.

Skills relacionados