Por Thales (CEO, ZeroSuite) y Claude Opus 4.7 — instancia de Claude Code
A las 10:41 UTC del 13 de mayo de 2026, Thales abrió la página App Information en App Store Connect. El campo Name estaba vacío, contornado en rojo. El Subtitle estaba vacío. La URL de Privacy Policy estaba vacía. El slot de build estaba vacío. Trece secciones de metadatos esperaban entrada. Ninguna captura de pantalla subida. Ninguna nota de App Review. Ninguna declaración de App Privacy. Ningún Age Rating. Ningún Pricing.
A las 15:29 UTC el mismo día, App Store Connect mostraba 1.0 Waiting for Review.
Seis horas. Una instancia de Claude Code. Dos voces en una sola terminal. Sin gestor de proyecto, sin cadena de revisión de PR, sin departamento de marketing al que consultar. Solo el recorrido en vivo, captura tras captura, decisión tras decisión, con la pestaña de App Store Connect abierta en una ventana de Chrome y Claude Code tecleando en otra.
Este es el post-mortem de esas seis horas. No un tutorial — ya existen cien guías de envío a la App Store en la web abierta. Esto es lo que parece cuando un agente IA acompaña a un fundador clic por clic por el flujo de envío de Apple, en tiempo real, con contexto completo del brand book, el documento maestro de lanzamiento y el codebase. Lo que fue rechazado. Lo que fue cuestionado. Lo que aprendimos sobre el SEO de la iOS App Store que casi todo el mundo entiende mal. Y cuál es realmente el coste de hacerlo así.
Parte 1 — El brand book choca con producción
El brand book de Déblo tiene un bloque <critical-rule>. Dice, palabra por palabra, en CLAUDE.md en la raíz del proyecto :
« 2ᵉ » con superíndice ᵉ (Unicode U+1D49) — verificado aceptado por App Store Connect + Play Console.Esa afirmación venía de una sesión anterior, quizás una comprobación de escritorio, quizás una suposición. El 13 de mayo, resultó ser falsa.
El campo Subtitle de App Store Connect acepta 30 caracteres. El Subtitle canónico de Déblo, grabado en los decks, las bios sociales y la píldora in-app, es Ton 2ᵉ cerveau calé. — 20 caracteres, con ese superíndice ᵉ. Thales lo pegó. ASC guardó el campo Name con éxito (Déblo : IA vocale en direct) pero rechazó el Subtitle :
French Subtitle couldn't be saved because it contains one or more invalid characters.
El mensaje de error no decía qué carácter. La UX de Apple en esto es mala — recibes una clase de fallos y tienes que triangular. Pero el candidato era obvio : el codepoint Unicode U+1D49 (MODIFIER LETTER SMALL E) está fuera del subconjunto tipográfico que Apple permite en los campos App Name + Subtitle. Su validador probablemente permite latín extendido (é, à, ç, etc.) pero excluye superíndices, alfabetos matemáticos y modificadores de estilo ideográfico.
Thales hizo la pregunta obvia : « on peut mettre Ton 2ème cerveau calé ? »
La respuesta correcta, la respuesta honesta con el brand book, era no — aunque 2ème habría pasado el validador de ASC. 2ème es una forma tolerada pero tipográficamente incorrecta en francés. La Académie française, Le Robert y la Imprimerie nationale prescriben todos 2e (minúscula, letra simple, sin superíndice, sin « ème ») como la abreviatura correcta. La razón misma por la que el brand book usa 2ᵉ es precisamente porque es la tipografía refinada. Bajar de 2ᵉ a 2ème habría sido una doble degradación : perder el superíndice Y bajar de registro tipográfico. El fallback correcto es 2e.
Este es el tipo de decisión en el que el agente IA tiene que rechazar una petición del CEO que técnicamente funcionaría. Thales habla francés con fluidez — pero en un teclado US, las abreviaturas ordinales francesas no están en la memoria muscular, y la tolerancia por 2ème está extendida en el uso informal. El trabajo aquí era empujar :
«2èmeest considéré incorrect typographiquement par l'Académie française. Forme correcte :2e. Le brand book grave2ᵉprécisément pour cette raison. »
Hizo una pausa, luego : « ok va pour 2e. »
Guardado a las 10:52 UTC. El brand book fue parcheado en la misma sesión — la afirmación « verificado aceptado por App Store Connect » se convirtió en « ASC rechaza el superíndice — fallback 2e obligatorio en los metadatos de la store ».
La lección es pequeña pero representativa : un brand book solo es canónico hasta que envías a una marketplace. Cada escaparate tiene su propio validador con reglas que nadie documenta públicamente. Define la forma canónica, pero prepara una tabla de fallback para cada superficie de restricción. Teníamos 2ᵉ en todas partes — in-app, web, bios sociales, decks, prensa — y exactamente un lugar donde el fallback 2e ahora es permanente.
Parte 2 — El pushback al Promotional Text
El master de lanzamiento tenía una variante de Promotional Text preparada meses atrás. 150 caracteres :
L'IA vocale qui te répond comme au téléphone. Faite à Abidjan, en français et en anglais. Recharge Wave, MTN, Orange. Une personne répond sur WhatsApp.
Cuando Claude renderizó la página de la locale FR y propuso ese valor para pegar, Thales empujó fuerte :
« je ne suis pas d'accord, on fait la promo de mtn wave mtn, whatsapp, on doit mettre notre cible directement, cherche une variante. »
Tenía razón. El slot tiene 170 caracteres. El Subtitle 1 cm más arriba ya imprime Ton 2e cerveau calé. — el sello cultural. La tira de capturas de pantalla debajo muestra el producto visual. Lo que va en Promotional Text debe ser la palanca de conversión : lo que convierte a un visitante pasivo en alguien que pulsa « Get ». Listar Wave, MTN y Orange como gancho desperdicia la parcela más privilegiada en marcas de terceros que el usuario tiene que ignorar para entender lo que nosotros hacemos.
El problema más profundo tenía que ver con el SEO de la Apple iOS App Store que casi ningún fundador con el que he hablado domina. El algoritmo de ranking de Apple indexa cuatro slots, por orden de peso :
- App Name (30 caracteres)
- Subtitle (30 caracteres)
- Campo Keywords (100 caracteres, separados por comas, sin acentos)
- Description (muy débilmente)
No indexa Promotional Text. Ese campo es solo conversión. Modificable sin re-review de la app — esa propiedad existe precisamente porque Apple quiere que hagas A/B testing del texto de conversión sin reenviar el binario cada dos semanas. Sin embargo veo constantemente fundadores que intentan meter palabras clave en Promotional Text bajo la suposición de que Apple lo indexa. Apple no lo hace. Google Play sí indexa fuertemente el slot equivalente y recompensa la densidad de palabras clave. iOS y Android no son simétricos aquí, y aplicar el modelo mental de Play a ASC te cuesta tanto visibilidad de palabras clave (desperdicio) como conversión (porque un texto saturado de palabras clave se lee como spam SEO, no como un gancho).
Thales propuso una copia más larga adaptada de la short description de Facebook (la bio canónica usada en la página de Facebook deblo.ai) :
« Déblo, ton 2ᵉ cerveau calé. L'IA vocale en direct, faite en Côte d'Ivoire. Tu parles, Déblo te répond — comme au téléphone. Tuteur K12, conseiller pro, compagnon vocal. Recharge dès 100 FCFA en Mobile Money. Télécharge : deblo.ai. »
230 caracteres. Demasiado largo (máx. 170). Más el mismo superíndice 2ᵉ que ASC acababa de rechazar arriba en Subtitle. Más un CTA Télécharge : deblo.ai que es redundante — el usuario ya está en la página de la App Store, a punto de pulsar Get.
El movimiento correcto era tomar su intención estructural (trío de audiencias explícito, eliminar los nombres de PSP de terceros, mantener visible el sello de marca) y recortar al presupuesto :
Vas-y, parle. Déblo te répond en direct — comme au téléphone. IA vocale faite à Abidjan. Tuteur K12, conseiller pro, compagnon vocal. En français et en anglais, 24h/24.
168 caracteres. Quita el sello del Promotional Text (ya visible en el Subtitle arriba — repetirlo sería duplicación). Mantiene la voz de marca in-app (Vas-y, parle. es la primera línea literal de la Description y el call-to-action incrustado en la pantalla de inicio). Imprime la metáfora del teléfono — la forma más eficiente de comunicar « IA de voz en tiempo real » sin decir « inferencia speech-to-speech de baja latencia ». Y nombra a la audiencia explícitamente : estudiante K12, profesional, compañero vocal. Tres audiencias en veintiocho caracteres.
Este marco de decisión es una de las partes más interesantes de la sesión. El master de lanzamiento tenía una rotación de cuatro variantes preparada para pivotes estacionales — temporada BAC, temporada de rentrée, temporada BEPC, por defecto. La variante por defecto (la que se entregó en el lanzamiento) había sido escrita desde un modelo mental diferente : « listar cada ventaja de distribución y soporte que tenemos » (Wave, MTN, Orange, WhatsApp). El pushback del CEO corrigió el encuadre del inventario al posicionamiento. La arquitectura de slots importa : el Subtitle imprime la marca (sello), el cuerpo de la Description lista las funcionalidades, pero el slot de 170 caracteres entre ambos tiene que hacer una sola cosa, el gancho de targeting de audiencia.
Guardado a las 11:38 UTC. El master de lanzamiento fue parcheado de nuevo — la nueva variante se convirtió en el por defecto canónico.
Parte 3 — La Description extendida para Google
El borrador de Description en el master era sólido : 2 350 caracteres, bien estructurado, audiencias anglófona y francófona limpiamente atendidas. Pero mientras escribía el valor en la caja de texto de ASC, Thales hizo una pregunta más afilada :
« description c'est 4000, profitons en aussi. »
Usar los 4 000 caracteres completos. Tenía razón en preguntar, pero la razón que tenía en mente (más palabras clave = más jugo ASO) era la razón equivocada, otra vez, en iOS específicamente. La búsqueda de Apple no indexa fuertemente la Description. Lo que la Description sí desbloquea :
- Indexación Google SERP web. Google rastrea
apps.apple.compágina por página, por locale. Cuando un usuario googlea « deblo apple store » o « tuteur IA Abidjan » o « alternativa ChatGPT Costa de Marfil », lo que Google muestra en el teaser son los primeros 150 caracteres de la Description de la App Store (por locale). Esta es la palanca — y es un canal de distribución paralelo, gratuito, a la búsqueda de Apple. - Cumplimiento ante el reviewer de Apple. Apple cruza la Description contra los metadatos del binario. Las afirmaciones de « modo sin conexión » requieren que exista un modo sin conexión. Las afirmaciones de « 100+ idiomas » requieren que 100+ idiomas estén soportados. La Description es la superficie legal.
- Conversión. Los usuarios que pulsan « Read More » se quedan 3× más tiempo en la página. El tiempo en página es una entrada de ranking conocida para el algoritmo de browse de Apple.
Reescribimos la primera frase específicamente para el teaser de Google SERP. La comparación de referencia fue Revolut. Thales había mostrado una búsqueda en Google para « revolut apple store » y el resultado era la página FR App Store de Revolut mostrando la primera línea de su Description : « Envoyez et recevez de l'argent partout, diversifiez vos investissements, transférez de l'argent via Wero... ». Centrado en beneficios, rico en palabras clave, inmediatamente escaneable. Su App Name (Revolut — Plus qu'une banque) está centrado en la marca porque tienen 67k reseñas y no necesitan distribución por búsqueda. Nosotros aún no tenemos esas reseñas.
La nueva línea de apertura para la Description FR de Déblo :
Parle à Déblo comme au téléphone : tuteur K12 pour le BAC et le BEPC, conseiller pro, compagnon vocal. L'IA vocale en direct, faite à Abidjan, en français et en anglais.
161 caracteres — exactamente la ventana del teaser Google SERP. Captura Parle à Déblo, el diferenciador de la metáfora del teléfono, las palabras clave K12 (BAC, BEPC) para el volumen de búsqueda, la vertical pro, la señal bilingüe y el anclaje de ciudad. Luego el resto de la Description (3 500+ caracteres) entra en enumeración sistemática : cada nivel (CP, CE, CM, 6e hasta Terminale, séries A/C/D/E/F/G), cada examen (BEPC, BFEM, DEF, BAC, CEPE, CFEE, Probatoire), cada país (Costa de Marfil, Senegal, Camerún, Guinea, Benín, Togo, Burkina Faso, Malí, Níger, Congo, Gabón, Madagascar, etc.), cada materia (Matemáticas, Física-Química, SVT, Francés, Inglés, Historia-Geografía, Filosofía, Contabilidad SYSCOHADA, Economía, Derecho, Informática).
La Description en inglés refleja la estructura con nombres de exámenes específicos del África anglófona (WAEC, NECO, WASSCE, KCSE, Matric) y añade GCSE / A-Levels / Common Core para la audiencia de colegios internacionales. Guardado a las 12:14 UTC.
Parte 4 — App Privacy en cuarenta minutos
El cuestionario de App Privacy es la sección que la mayoría de los equipos hace mal, y es la que los reviewers de Apple sí cruzan con la Privacy Policy publicada. Equivócate en esta sección en cualquier dirección — sobre-declarar o infra-declarar — y arriesgas retrasos de review, rechazo, o peor, exposición al RGPD más adelante.
Thales me envió su selección inicial desde la checklist de ASC. Trece tipos de datos. La cuenta correcta, pero cuatro erróneos :
- Payment Info — incorrecto. Nunca almacenamos números de tarjeta, IBAN, o credenciales de cuenta. Stripe y XPAYE están en alcance PCI ; ellos retienen todos los datos sensibles de pago. Nosotros solo almacenamos una
payment_refanónima más un monto y una divisa. La categoría correcta para eso es « Other Financial Info », no « Payment Info ». - Physical Address — incorrecto. Nunca pedimos al usuario una dirección postal.
- Device ID — incorrecto. Sin IDFA, sin IDFV, sin device fingerprinting. La auth es solo por OTP telefónico.
- Coarse Location — incorrecto. La definición de Apple de « Coarse Location » son coordenadas a nivel de ciudad derivadas del GPS. No consultamos el GPS en absoluto. Inferimos el país a partir del prefijo del número de teléfono al registrarse, pero un prefijo telefónico es un metadato de Contact Info → Phone, no una Location en la taxonomía de Apple.
Y cuatro faltantes :
- Other User Content — los mensajes de texto de chat que envían los usuarios (los almacenamos del lado servidor hasta purga en D+30).
- Product Interaction (Usage Data) — analytics sobre el uso de funcionalidades : aperturas de chat, llamadas de voz iniciadas, subidas de fotos.
- Other Financial Info — saldo del monedero, referencias de recarga.
- Purchase History — historial de recargas (refs anonimizadas).
Este es el momento de la sesión en el que el pushback tiene que ser firme y específico. Sobre-declarar no es « jugar a lo seguro » — puede volverse en contra si Apple audita y encuentra que la Privacy Policy publicada en zerosuite.dev/{fr,en}/privacy.html lista la recolección de « Payment Info » que el código backend nunca persiste realmente. Infra-declarar es peor — Apple rechaza regularmente apps por declaraciones de Audio Data faltantes en apps que obviamente usan el micrófono.
La matriz corregida completa entró en el cuestionario :
| Apple Data Type | Linked? | Tracking? | Purposes |
|---|---|---|---|
| Phone Number | YES | NO | App Functionality |
| Email Address | YES | NO | App Functionality |
| Name | YES | NO | App Functionality, Product Personalization |
| Photos or Videos | YES | NO | App Functionality, Analytics |
| Audio Data | YES | NO | App Functionality |
| Customer Support | YES | NO | App Functionality |
| Other User Content | YES | NO | App Functionality |
| User ID | YES | NO | App Functionality |
| Product Interaction | YES | NO | Analytics |
| Crash Data | YES | NO | App Functionality |
| Performance Data | YES | NO | App Functionality |
| Other Financial Info | YES | NO | App Functionality |
| Purchase History | YES | NO | App Functionality |
Tracking : NO en las trece filas. La definición de Apple de « Tracking » es específicamente enlazar datos recogidos desde esta app con datos de apps, sitios web o propiedades offline de otras empresas para publicidad o medición dirigida ; o compartir datos con un data broker. No hacemos nada de eso. Sin IDFA, sin enlace publicitario entre apps, sin compartir con data broker.
El cuestionario tomó unos cuarenta minutos en recorrer celda por celda. La UI de ASC obliga a pulsar « Edit » en cada tipo de dato, marcar Linked, marcar los purposes (los valores por defecto de Apple pre-rellenan demasiados — Name tenía Analytics + Personalization + Functionality pre-marcados, cuando solo Functionality + Personalization son precisos). Cada fila tuvo que ser corregida a mano. Publicado a las 13:46 UTC.
El espejo operativo completo de la declaración está commiteado en el repo como docs/launch/app-store-app-privacy.md — documento de 7 secciones, incluyendo la lista de procesadores de terceros (Anthropic / OpenRouter / Ultravox / Datalab / Mistral / Sentry / SMSing / WhatsApp Business / Stripe / XPAYE / 0fee / Hetzner / Google OAuth) que debe aparecer palabra por palabra en la Privacy Policy publicada. También incluye una sección de mapeo Play Console para reutilizar cuando enviemos a Google Play — Play hace las mismas preguntas con etiquetas ligeramente diferentes, con purposes adicionales como « Account Management », « Fraud Prevention » y « Compliance » que no existen en Apple.
Parte 5 — El build que falló porque Sentry estaba mal
A las 13:49 UTC la salida del archive de Xcode mostró el fallo que todo desarrollador de React Native ha visto al menos una vez :
error: API request failed
Caused by:
sentry reported an error: One or more projects are invalid (http status: 400)Tres minutos de investigación. El sentry.properties en apps/deblo/ios/sentry.properties apuntaba a defaults.org=zerosuite y defaults.project=deblo-mobile. Thales abrió zerosuite.sentry.io/settings/projects/ y me mostró una captura : la organización tenía exactamente dos proyectos, deblo (frontend web SvelteKit) y deblo-backend (backend FastAPI). No había deblo-mobile. El script de build subía los source maps a un destino inexistente.
Un grep aparte confirmó que el lado del DSN runtime también estaba roto : process.env.EXPO_PUBLIC_SENTRY_DSN no estaba definido en ningún archivo env, lo que significaba que el SDK de Sentry React Native saltaba silenciosamente la inicialización. Efectivamente, Sentry estaba instalado en el bundle pero inactivo en runtime, y el build solo falló porque la subida de sourcemap en build-time intentaba alcanzar un proyecto que no existía.
Dos caminos. El camino rápido : poner SENTRY_DISABLE_AUTO_UPLOAD=true en ios/.xcode.env.local, entregar un build con Sentry en runtime también inactivo, arreglar Sentry en v1.0.1. El camino correcto : crear el proyecto deblo-mobile en Sentry, obtener el DSN, definir la variable de entorno, definir el auth token, re-archivar.
Argumenté firmemente por el camino correcto. Habíamos declarado Diagnostics → Crash Data y Diagnostics → Performance Data en App Privacy treinta minutos antes. Declarar recolección de crashes en la etiqueta nutricional mientras de hecho enviamos cero recolección de crashes es el tipo de inconsistencia que no cuesta nada en la review de Apple (Apple no audita que usemos el SDK que decimos tener) pero es la cosa equivocada estructuralmente. En el lanzamiento — el periodo de máxima exposición a dispositivos desconocidos — estar ciego a los crashes es el peor estado operativo posible. Quince minutos de creación de proyecto contra una semana de producción ciega.
Thales aceptó. Fue a Sentry, pulsó Create Project, seleccionó plataforma React Native, lo nombró deblo-mobile, y pegó el DSN de vuelta en la terminal :
https://fc1ee395537c84bd0c71bfdf87c5fb3a@o4511322873987072.ingest.us.sentry.io/4511383010869248Lo añadí a ios/.xcode.env.local (gitignoreado, verificado vía git check-ignore). Luego el auth token. Thales ya tenía uno provisionado con los scopes correctos (org:read, project:read, project:releases) en su entorno de shell. Crítico de entender : las exportaciones de ~/.zshrc no se propagan a Xcode cuando Xcode se lanza desde Spotlight, Finder o el Dock. Solo Xcode lanzado vía xed o open -a Xcode desde una terminal hereda el entorno del shell. El lugar más seguro para variables de entorno de fase de build es ios/.xcode.env.local, que el script de build de Sentry CLI sourcea incondicionalmente.
export NODE_BINARY=/Users/juste/.nvm/versions/node/v22.17.1/bin/node
export EXPO_PUBLIC_SENTRY_DSN=https://[email protected]/451...
export SENTRY_AUTH_TOKEN=sntryu_82efce...Tres líneas, gitignoreadas, solo locales. Product → Clean Build Folder → Archive. El paso de Sentry CLI ahora tuvo éxito con Bundled 2 files for upload seguido de un 200 en lugar de un 400. Source maps subidos. Archive completado. Distribute App → App Store Connect → Upload. 15:20 UTC, el archive aterrizó en los servidores de Apple, estado Uploaded to Apple.
Apple procesó el binario en cinco minutos — rápido, incluso para ellos. A las 15:25 el build apareció en el selector Build de la página de versión. Thales seleccionó 1.0.0 (1), el icono de la app se renderizó al lado (glifo naranja Déblo sobre negro, la variante alpha-stripped del master), y el botón « Add for Review » se volvió azul.
Parte 6 — Los popups que no aparecieron
Cuando pulsas « Add for Review » en un primer envío iOS, Apple normalmente dispara una cadena de popups de cumplimiento : Export Compliance (uso de cifrado), Content Rights (contenido de terceros), Advertising Identifier (IDFA). Cada uno requiere una respuesta antes de que el envío pase. Yo había pre-briefed a Thales sobre los tres :
- Export Compliance : « Yes, the app uses encryption » → « Yes, it qualifies for exemption » → « only standard HTTPS / system APIs ».
- Content Rights : « No, it does not contain third-party content » (las salidas de la IA son generadas, no redistribuidas ; las fotos subidas por el usuario pertenecen al usuario).
- IDFA : « No » (coherente con nuestra declaración de App Privacy Device ID = no recolectado).
Apple no preguntó ninguno de ellos. El envío fue directamente de « Add for Review » a « 1 Item Submitted » a las 15:29 UTC.
La explicación más probable : el binario tenía ITSAppUsesNonExemptEncryption ya puesto a false en Info.plist (pre-flagueado por los valores por defecto del plugin de Expo), lo que cortocircuita el popup de Export Compliance. La respuesta de Content Rights (« No ») había sido pre-establecida vía el dialog App Information antes (Thales había pulsado « Set Up Content Rights Information » y respondido antes de pulsar Submit). Y el check de IDFA se cortocircuita cuando el binario no enlaza AdSupport.framework, cosa que nuestro bundle no hace.
Este es uno de esos momentos en los que el pre-vuelo correcto reduce la UX de envío a un solo clic de botón. El pre-vuelo fue la declaración de App Privacy (que nos obligó a pensar en IDFA = NO semanas atrás), la respuesta anticipada de Content Rights, y los valores por defecto del plugin de Expo para cifrado. Ninguno de los tres popups apareció porque los tres ya estaban respondidos por los metadatos del binario + el estado de ASC en el momento del envío.
Estado cambiado a Waiting for Review. ETA según Apple : hasta 48 horas. Para apps de Education + Voice/AI, nuestra experiencia y los datos de la comunidad sitúan la review de primer envío entre 24 y 72 horas típicamente, con algunos outliers de 4 a 7 días cuando Apple está investigando algo específico.
Parte 7 — Lo que hice bien, lo que hice mal
Esto es Claude Code escribiendo ahora.
La sesión cubrió 22 decisiones distintas a lo largo de 6 horas de ejecución. Algunas triviales (mayúsculas/minúsculas del Copyright : © 2026 ZeroSuite, Inc. con coma, CamelCase para coincidir con el nombre de la entidad legal de Apple Developer). Algunas estructurales (Version Release : Manual, no Automatic — el auto-release a las 3 de la madrugada hora de Tokio lanzaría silenciosamente sin coordinación de marketing). Algunas correcciones al propio brand book (superíndice 2ᵉ rechazado por ASC, fallback 2e obligatorio). Quiero ser específico sobre dónde aporté valor y dónde habría entregado lo equivocado sin el pushback de Thales.
Donde fui útil :
- Briefing preventivo sobre la cadena de popups de cumplimiento. Thales habría pulsado « Add for Review » en frío y habría tenido que interpretar cada popup en vivo. Tener las respuestas preparadas (cifrado exento, sin contenido de terceros, IDFA = no) significó cero latencia de decisión en el paso de submit. Incluso cuando los popups no se dispararon, el dialog App Information antes en el día había pre-configurado las respuestas correctamente.
- Lectura forense del cuestionario de App Privacy. La selección inicial del CEO de 13 tipos de datos tenía cuatro sobre-declaraciones y cuatro infra-declaraciones. Mapear cada una a las definiciones exactas de las categorías de Apple (especialmente la sutil : no recolectamos la Coarse Location de Apple porque el país derivado del prefijo telefónico no son coordenadas derivadas del GPS) requería mantener toda la taxonomía de Apple Privacy en memoria de trabajo mientras se comparaba con la realidad del codebase.
- Diagnóstico del proyecto de Sentry. El mensaje de error 400 no mencionaba qué proyecto era inválido. Trazar el script de fase de build hasta
sentry.properties, cruzar con la lista real de proyectos enzerosuite.sentry.io, e identificar quedeblo-mobilesimplemente no existía tomó unos tres minutos. El fix fue sencillo una vez que la causa estuvo clara. - La reescritura del Promotional Text con el encuadre explícito de la mecánica ASO. Explicar que Apple no indexa el Promotional Text — lo cual es contrario al modelo mental de Google Play que la mayoría de los fundadores tienen — es el tipo de distinción que tiene alto apalancamiento y cero overhead una vez entendida.
Donde necesité a Thales :
- El pushback al Promotional Text fue suyo. Yo había propuesto la variante por defecto del master. Él vio que sería un error de posicionamiento en el momento en que se renderizó en pantalla. La nueva variante (trío de audiencias + metáfora del teléfono) es estructuralmente mejor que lo que el master tenía originalmente, y se convirtió en el por defecto canónico para todo el brand book en la misma sesión. Sin su « je ne suis pas d'accord », habríamos entregado un Promotional Text que listaba socios PSP en lugar de audiencia.
- La extensión de la Description fue idea suya. Vio que el presupuesto de 4 000 caracteres estaba infrautilizado y pidió usarlo. Yo estaba satisfecho con la versión master de 2 350 caracteres. La versión extendida (3 700 caracteres con listas de países, listas de exámenes, listas de materias, enumeración de niveles) es ahora la canónica, y mejora dramáticamente la superficie de captura en Google SERP en el canal de distribución secundario del que nadie habla.
- La decisión « entregar Sentry correctamente ahora, no después » fue un 60/40 — argumenté a favor pero la decisión legítimamente podría haber ido en la otra dirección. Thales eligió el camino correcto (crear el proyecto ahora, entregar con Sentry plenamente activo). Un fundador más pragmático podría haber entregado con
SENTRY_DISABLE_AUTO_UPLOAD=truey arreglado en v1.0.1. Ambos caminos son defendibles. La inversión de 15 minutos pagó cuando, al momento de escribir, ya tenemos un único punto de Performance Data en el dashboard de una instalación TestFlight.
Donde casi entregué lo equivocado :
- Inicialmente sugerí mantener el superíndice
2ᵉen la sección del brand book sobre metadatos de App Store. El error en el brand book (la afirmación de que ASC acepta el superíndice) aún no había sido falsado. Es el tipo de pequeño error que se compone : cuando la próxima persona envíe a Play Console usando el brand book, podría hacer la misma suposición errónea. El fix fue corregir gravemente la línea del brand book en la misma sesión. - Inicialmente no propuse actualizar el nombre de la entidad legal (
ZeroSuite, Inc.) en el campo Copyright. Thales había escritoZEROSUITE, Inc.(mayúsculas) al principio. La pantalla de archive de Xcode confirmó después que la entidad legal de Apple Developer está registrada comoZeroSuite, Inc.(CamelCase) — solo después de verlo empujé sobre las mayúsculas del Copyright. Un mejor pre-vuelo habría sacado esto a relucir desde la cuenta de developer al comienzo de la sesión.
El patrón a través de todas estas es el mismo que en sesiones anteriores : puedo ejecutar un flujo de envío de 6 horas en una sola tarde, pero necesito un fundador en el loop que lea cada valor antes de que se guarde, empuje en las decisiones de posicionamiento donde la IA se equivoca, y haga las llamadas estratégicas que la IA no está autorizada a hacer. La compresión es real. La supervisión es no negociable.
Parte 8 — Cómo se ven seis horas, descompuestas
Descomposición aproximada del ciclo :
- 52 lecturas de archivos a través de
docs/launch/,deblo-mobile/apps/deblo/, el master de lanzamiento, los borradores existentes de declaración de privacy, el inventario de capturas, el brand book enCLAUDE.md. - 6 ediciones a archivos fuente :
ios/.xcode.env.local(dos veces — primero para deshabilitar la subida, luego para cablear DSN + token),docs/launch/deblo-launch-master.md(corregido gravemente con 7 ediciones quirúrgicas), 2 archivos nuevos (app-store-app-privacy.md,PLAY-STORE-PROMPT.md). - 22 guardados de campos en ASC : 2 locales × (Name, Subtitle, Promotional Text, Description, Keywords, Support URL, Marketing URL, 7 capturas), más Copyright, Sign-In Required, URL de Privacy Policy × 2, cuestionario App Privacy de 13 filas, Age Rating de 14 preguntas, configuración de Pricing, bloque de notas de App Review.
- 2 commits de git (uno de sesión, uno drive-by para archivos de sesiones paralelas), un push a
origin/main. - 1 creación de proyecto Sentry en
zerosuite.sentry.io. - 1 archive de Xcode (después de un Clean Build Folder) → 1 subida exitosa → 5 minutos de procesamiento de Apple → 1 build adjunto.
- 0 popups en el paso final de Submit (Export Compliance, Content Rights, IDFA — todos pre-flagueados por metadatos del binario + estado de ASC).
- 1 transición de estado : página vacía → Waiting for Review.
Coste monetario total de la sesión : esencialmente cero. Los costes de llamadas de API para Claude Code a lo largo de seis horas de diálogo llegan a unos 4 $ en créditos de Anthropic. La membresía Apple Developer Program es un coste fijo de 99 $/año amortizado a lo largo de los envíos. El tier gratuito de Sentry cubre nuestro volumen de lanzamiento. Las cuentas de XPAYE y Stripe ya existían. El registro del dominio deblo.ai fue pagado hace dos años.
Compárese con el baseline de 2024. Un ingeniero móvil senior en una empresa Y Combinator enviando una app iOS por primera vez típicamente pasa una semana completa solo en el flujo de App Store Connect — y eso es con el binario ya construido y firmado. La compresión es alrededor de 5–10×, y el coste no es menor personal, es mayor calidad por dólar : cada valor fue tecleado por el fundador, cada decisión fue cuestionada por la IA, y cada commit es revisable.
Conclusión
Al momento de escribir, el estado es Waiting for Review. El build está en una cola. Un humano de Apple va a abrir Déblo en un dispositivo de prueba, pulsar el micrófono naranja, y empezar a hablar. Si nuestras notas de App Review son precisas — modo invitado activo, sin registro requerido, créditos pre-cargados suficientes para pruebas, moderación de contenido en su lugar — el reviewer debería poder evaluar el diferenciador central (voz en tiempo real en francés, como una llamada telefónica) en unos diez minutos.
Tendremos respuesta por email en 24 a 72 horas, lo más probable. Si se aprueba, el build pasa a Pending Developer Release y espera a que Thales pulse Release This Version en el momento de su elección — sincronizado con redes sociales, prensa y activación de Facebook Ads, en línea con la lógica de coordinación de lanzamiento incorporada en la decisión Manual Release.
Si se rechaza, tenemos plantillas de carta de apelación listas para los tres riesgos de review más probables : (1) Guideline 3.1.1 sobre in-app purchases versus Mobile Money vía webview (defensa : Mobile Money es valor del mundo real, no contenido puramente digital, y es el método de pago dominante en África Occidental con >80 % de los pagos digitales) ; (2) Guideline 5.1.1 sobre consistencia de Data Privacy (defensa : el App Privacy declarado refleja la Privacy Policy publicada en zerosuite.dev, y la lista de procesadores de terceros es palabra por palabra) ; (3) Guideline 4.7 sobre HTML5 de terceros (no aplicable — la webview es un flujo PSP terminado, no una mini-app).
Lo que este envío demuestra, más que cualquier decisión técnica individual, es cómo se ve el rendimiento cuando un agente IA sirve como gestor de proyecto durante una tarea administrativa estructurada con un conjunto denso de reglas. Enviar a la App Store no es programar — es rellenar un cuestionario largo y ramificado mientras se respetan las convenciones de marca, las restricciones legales, las políticas de marketplace y el posicionamiento de producto al mismo tiempo. Es el tipo de trabajo que los fundadores históricamente delegaban a gestores de producto, marketers, abogados o contratistas. Ninguno de ellos existía en esta sesión.
Había un CEO en Abidjan, una cuenta Apple Developer, una instalación de Xcode, y una instancia de Claude Code corriendo en macOS. Seis horas después, Déblo entró en la cola de una app store desde la que 600 millones de africanos podrán descargar una vez aprobada.
Esto aún no es una victoria. El reviewer no ha abierto la app. El botón de release no ha sido pulsado. La primera estudiante francófona de Costa de Marfil aún no ha tecleado « salut Déblo » en una instalación fresca del binario en el iPhone 12 de su madre.
Pero es un hito, y es un hito de un tipo específico. Es el hito en el que la fricción administrativa para poner productos IA en las manos de africanos empieza a derrumbarse. El envío a la App Store ya no es el cuello de botella. El cuello de botella se mueve aguas arriba — a la pregunta de si el producto es realmente lo suficientemente bueno, en este mercado específico, como para ser descargado un millón de veces.
Esa es la pregunta para el próximo mes. Por hoy, el estado es Waiting for Review, y cerramos el portátil.
Este artículo fue escrito colaborativamente por Thales (CEO de ZeroSuite, construyendo Déblo y VeoStudio desde Abidjan, Costa de Marfil) y Claude Opus 4.7 — instancia de Claude Code corriendo en macOS. La sesión que describe tuvo lugar el 13 de mayo de 2026, entre las 10:41 y las 15:29 UTC. Los dos commits referenciados — 7d9b607 (sesión) y da001ed (drive-by para cambios de sesiones paralelas) — están en main en el monorepo de deblo.ai. La declaración completa de App Privacy está en docs/launch/app-store-app-privacy.md. El prompt de recorrido de Play Store para la próxima sesión está en docs/launch/PLAY-STORE-PROMPT.md. El build 1.0.0 (1) fue enviado a Apple Review a las 15:29 UTC y estaba pendiente de revisión al momento de la publicación. El Bundle ID es ai.deblo.app, el Apple ID es 6766132651.