Par Thales (CEO, ZeroSuite) et Claude Opus 4.7 — instance Claude Code
À 10h41 UTC le 13 mai 2026, Thales a ouvert la page App Information dans App Store Connect. Le champ Name était vide, encadré en rouge. Le Subtitle était vide. L'URL de Privacy Policy était vide. Le slot de build était vide. Treize sections de métadonnées attendaient une saisie. Aucune capture d'écran téléversée. Aucune note d'App Review. Aucune déclaration App Privacy. Aucun Age Rating. Aucun Pricing.
À 15h29 UTC le même jour, App Store Connect affichait 1.0 Waiting for Review.
Six heures. Une instance Claude Code. Deux voix dans un seul terminal. Pas de chef de projet, pas de chaîne de revue PR, pas de département marketing à consulter. Juste le déroulé en direct, capture d'écran après capture d'écran, décision après décision, avec l'onglet App Store Connect ouvert dans une fenêtre Chrome et Claude Code en train de taper dans une autre.
Voici le post-mortem de ces six heures. Pas un tutoriel — il existe déjà une centaine de guides de soumission App Store sur le web ouvert. Voici à quoi ça ressemble lorsqu'un agent IA accompagne un fondateur clic par clic dans le flux de soumission d'Apple, en temps réel, avec le contexte complet du brand book, du document maître de lancement et du codebase. Ce qui a été rejeté. Ce qui a été remis en cause. Ce que nous avons appris sur le SEO de l'iOS App Store que presque tout le monde se trompe. Et le coût réel de procéder ainsi.
Partie 1 — Le brand book heurte la production
Le brand book de Déblo contient un bloc <critical-rule>. Il dit, mot pour mot, dans CLAUDE.md à la racine du projet :
« 2ᵉ » avec exposant ᵉ (Unicode U+1D49) — vérifié accepté par App Store Connect + Play Console.Cette affirmation venait d'une session précédente, peut-être un test desktop, peut-être une supposition. Le 13 mai, il s'est avéré qu'elle était fausse.
Le champ Subtitle d'App Store Connect accepte 30 caractères. Le Subtitle canonique de Déblo, gravé dans les decks, les bios sociales et la pastille in-app, est Ton 2ᵉ cerveau calé. — 20 caractères, avec cet exposant ᵉ. Thales l'a collé. ASC a enregistré le champ Name avec succès (Déblo : IA vocale en direct) mais a rejeté le Subtitle :
French Subtitle couldn't be saved because it contains one or more invalid characters.
Le message d'erreur ne disait pas quel caractère. L'UX d'Apple sur ce point est mauvaise — on obtient une classe d'échecs et il faut trianguler. Mais le candidat était évident : le codepoint Unicode U+1D49 (MODIFIER LETTER SMALL E) est en dehors du sous-ensemble typographique qu'Apple permet dans les champs App Name + Subtitle. Leur validateur autorise probablement le latin étendu (é, à, ç, etc.) mais exclut les exposants, les alphabets mathématiques et les modificateurs de style idéographique.
Thales a posé la question évidente : « on peut mettre Ton 2ème cerveau calé ? »
La bonne réponse, la réponse honnête vis-à-vis du brand book, était non — même si 2ème serait passé au validateur d'ASC. 2ème est une forme tolérée mais typographiquement incorrecte en français. L'Académie française, Le Robert et l'Imprimerie nationale prescrivent toutes 2e (minuscule, lettre simple, pas d'exposant, pas de « ème ») comme l'abréviation correcte. La raison même pour laquelle le brand book utilise 2ᵉ est précisément parce que c'est la typographie raffinée. Retomber de 2ᵉ à 2ème aurait été un double downgrade : perdre l'exposant ET descendre dans le registre typographique. Le repli correct est 2e.
C'est le genre de décision où l'agent IA doit refuser une demande du CEO qui fonctionnerait techniquement. Thales est francophone — mais sur un clavier US, les abréviations ordinales françaises ne sont pas dans la mémoire musculaire, et la tolérance pour 2ème est répandue dans l'usage informel. Le travail ici était de pousser :
«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. »
Il a marqué une pause, puis : « ok va pour 2e. »
Enregistré à 10h52 UTC. Le brand book a été patché dans la même session — l'affirmation « vérifié accepté par App Store Connect » est devenue « ASC rejette l'exposant — repli 2e obligatoire dans les métadonnées du store ».
La leçon est petite mais représentative : un brand book n'est canonique que jusqu'à ce que vous soumettiez à une marketplace. Chaque vitrine a son propre validateur avec des règles que personne ne documente publiquement. Définissez la forme canonique, mais préparez une table de repli pour chaque surface de contrainte. Nous avions 2ᵉ partout — in-app, web, bios sociales, decks, presse — et exactement un endroit où le repli 2e est désormais permanent.
Partie 2 — Le pushback sur le Promotional Text
Le master de lancement avait une variante de Promotional Text préparée des mois auparavant. 150 caractères :
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.
Quand Claude a rendu la page de la locale FR et a proposé cette valeur à coller, Thales a poussé fort :
« je ne suis pas d'accord, on fait la promo de mtn wave mtn, whatsapp, on doit mettre notre cible directement, cherche une variante. »
Il avait raison. Le slot fait 170 caractères. Le Subtitle 1 cm plus haut imprime déjà Ton 2e cerveau calé. — le tampon culturel. Le bandeau de captures d'écran en dessous montre le produit visuel. Ce qui doit aller dans Promotional Text, c'est le levier de conversion : ce qui transforme un visiteur passif en quelqu'un qui appuie sur « Get ». Lister Wave, MTN et Orange comme accroche gaspille la plus précieuse parcelle de terrain sur des marques tierces que l'utilisateur doit ignorer pour comprendre ce que nous faisons.
Le problème plus profond concernait le SEO de l'Apple iOS App Store que presque aucun fondateur à qui j'ai parlé ne maîtrise. L'algorithme de classement d'Apple indexe quatre slots, par ordre de poids :
- App Name (30 caractères)
- Subtitle (30 caractères)
- Champ Keywords (100 caractères, séparés par des virgules, sans accents)
- Description (très faiblement)
Il n'indexe pas le Promotional Text. Ce champ est uniquement conversionnel. Modifiable sans re-review de l'app — cette propriété existe précisément parce qu'Apple veut que vous fassiez de l'A/B testing sur les textes de conversion sans resoumettre le binaire toutes les deux semaines. Pourtant je vois constamment des fondateurs essayer de bourrer des mots-clés dans Promotional Text en supposant qu'Apple l'indexe. Apple ne le fait pas. Google Play indexe lourdement le slot équivalent et récompense la densité de mots-clés. iOS et Android ne sont pas symétriques ici, et appliquer le modèle mental de Play à ASC vous coûte à la fois la visibilité sur les mots-clés (gaspillage) et la conversion (parce qu'un texte bourré de mots-clés se lit comme du spam SEO, pas comme une accroche).
Thales a proposé une copie plus longue adaptée de la short description Facebook (la bio canonique utilisée sur la page 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 caractères. Trop long (max 170). Plus le même exposant 2ᵉ qu'ASC venait de rejeter à l'étage du dessus dans Subtitle. Plus un CTA Télécharge : deblo.ai redondant — l'utilisateur est déjà sur la page de l'App Store, sur le point d'appuyer sur Get.
Le bon coup était de prendre son intention structurelle (trio d'audiences explicite, supprimer les noms des PSP tiers, garder le tampon de marque visible) et de tailler au budget :
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 caractères. Supprime le tampon du Promotional Text (déjà visible dans le Subtitle au-dessus — le répéter aurait été un doublon). Garde la voix de marque in-app (Vas-y, parle. est la première ligne littérale de la Description et le call-to-action intégré dans l'écran d'accueil). Imprime la métaphore du téléphone — la manière la plus efficace de communiquer « IA vocale temps réel » sans dire « inférence speech-to-speech à faible latence ». Et nomme l'audience explicitement : élève K12, professionnel, compagnon vocal. Trois audiences en vingt-huit caractères.
Ce cadre de décision est l'une des parties les plus intéressantes de la session. Le master de lancement avait une rotation de quatre variantes préparée pour les pivots saisonniers — saison BAC, saison rentrée, saison BEPC, défaut. La variante par défaut (celle livrée au lancement) avait été écrite à partir d'un modèle mental différent : « lister chaque distribution et avantage support que nous avons » (Wave, MTN, Orange, WhatsApp). Le pushback du CEO a corrigé le cadrage : passer de l'inventaire au positionnement. L'architecture des slots compte : le Subtitle imprime la marque (tampon), le corps de la Description liste les fonctionnalités, mais le slot de 170 caractères entre les deux doit faire une seule chose, l'accroche de ciblage d'audience.
Enregistré à 11h38 UTC. Le master de lancement a été patché à nouveau — la nouvelle variante est devenue le défaut canonique.
Partie 3 — La Description étendue pour Google
Le brouillon de Description dans le master était solide : 2 350 caractères, bien structuré, audience anglophone et francophone proprement adressée. Mais en tapant la valeur dans la zone de texte d'ASC, Thales a posé une question plus aiguë :
« description c'est 4000, profitons en aussi. »
Utiliser les 4 000 caractères complets. Il avait raison de demander, mais la raison qu'il avait en tête (plus de mots-clés = plus de jus ASO) était la mauvaise raison, encore une fois, sur iOS spécifiquement. La recherche d'Apple n'indexe pas lourdement la Description. Ce que la Description débloque en revanche :
- L'indexation Google SERP web. Google crawle
apps.apple.compage par page, par locale. Quand un utilisateur tape sur Google « deblo apple store » ou « tuteur IA Abidjan » ou « alternative ChatGPT Côte d'Ivoire », ce que Google affiche dans le teaser, c'est les 150 premiers caractères de la Description App Store (par locale). C'est le levier — et c'est un canal de distribution parallèle, gratuit, à la recherche Apple. - La conformité du reviewer Apple. Apple vérifie la Description contre les métadonnées du binaire. Les affirmations de « mode hors ligne » nécessitent qu'un mode hors ligne existe. Les affirmations de « 100+ langues » nécessitent que 100+ langues soient supportées. La Description est la surface légale.
- La conversion. Les utilisateurs qui cliquent « Read More » restent 3× plus longtemps sur la page. Le temps passé sur la page est un signal de classement connu pour l'algorithme de browse d'Apple.
Nous avons réécrit la première phrase spécifiquement pour le teaser Google SERP. La comparaison de référence était Revolut. Thales avait montré une recherche Google sur « revolut apple store » et le résultat était la page FR App Store de Revolut affichant la première ligne de leur Description : « Envoyez et recevez de l'argent partout, diversifiez vos investissements, transférez de l'argent via Wero... ». Centré sur les bénéfices, riche en mots-clés, immédiatement scannable. Leur App Name (Revolut — Plus qu'une banque) est centré sur la marque parce qu'ils ont 67k avis et n'ont pas besoin de la distribution recherche. Nous n'avons pas encore ces avis.
La nouvelle ligne d'ouverture de 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 caractères — exactement la fenêtre du teaser Google SERP. Capture Parle à Déblo, le différenciateur de la métaphore téléphonique, les mots-clés K12 (BAC, BEPC) pour le volume de recherche, la verticale pro, le signal bilingue, et l'ancrage géographique. Puis le reste de la Description (3 500+ caractères) part dans une énumération systématique : chaque niveau (CP, CE, CM, 6e à Terminale, séries A/C/D/E/F/G), chaque examen (BEPC, BFEM, DEF, BAC, CEPE, CFEE, Probatoire), chaque pays (Côte d'Ivoire, Sénégal, Cameroun, Guinée, Bénin, Togo, Burkina Faso, Mali, Niger, Congo, Gabon, Madagascar, etc.), chaque matière (Mathématiques, Physique-Chimie, SVT, Français, Anglais, Histoire-Géo, Philosophie, Comptabilité SYSCOHADA, Économie, Droit, Informatique).
La Description anglaise reflète la structure avec des noms d'examens spécifiques à l'Afrique anglophone (WAEC, NECO, WASSCE, KCSE, Matric) et ajoute GCSE / A-Levels / Common Core pour l'audience des écoles internationales. Enregistré à 12h14 UTC.
Partie 4 — App Privacy en quarante minutes
Le questionnaire App Privacy est la section que la plupart des équipes se trompent, et c'est celle que les reviewers d'Apple croisent activement avec la Privacy Policy publiée. Trompez-vous dans cette section dans un sens ou dans l'autre — sur-déclarer ou sous-déclarer — et vous risquez des retards de review, un rejet, ou pire, une exposition RGPD ultérieure.
Thales m'a envoyé sa sélection initiale depuis la checklist ASC. Treize types de données. Le bon compte, mais quatre fautifs :
- Payment Info — faux. Nous ne stockons jamais de numéros de carte, d'IBAN, ou d'identifiants de compte. Stripe et XPAYE sont dans le périmètre PCI ; ils détiennent toutes les données de paiement sensibles. Nous stockons seulement une
payment_refanonyme plus un montant et une devise. La bonne catégorie pour cela est « Other Financial Info », pas « Payment Info ». - Physical Address — faux. Nous ne demandons jamais à l'utilisateur d'adresse postale.
- Device ID — faux. Pas d'IDFA, pas d'IDFV, pas de device fingerprinting. L'auth est uniquement par OTP téléphonique.
- Coarse Location — faux. La définition d'Apple de « Coarse Location » est des coordonnées au niveau de la ville dérivées du GPS. Nous n'interrogeons pas du tout le GPS. Nous inférons le pays à partir du préfixe du numéro de téléphone à l'inscription, mais un préfixe téléphonique est une métadonnée de Contact Info → Phone, pas une Location dans la taxonomie d'Apple.
Et quatre manquants :
- Other User Content — les messages texte de chat envoyés par les utilisateurs (nous les stockons côté serveur jusqu'à purge à J+30).
- Product Interaction (Usage Data) — analytics sur l'usage des fonctionnalités : ouvertures de chat, appels vocaux démarrés, uploads de photos.
- Other Financial Info — solde du portefeuille, références de recharge.
- Purchase History — historique de recharge (refs anonymisées).
C'est le moment de la session où le pushback doit être ferme et spécifique. Sur-déclarer n'est pas « jouer la sécurité » — cela peut se retourner contre vous si Apple audite et trouve que la Privacy Policy publiée sur zerosuite.dev/{fr,en}/privacy.html liste la collecte de « Payment Info » que le code backend ne persiste jamais réellement. Sous-déclarer est pire — Apple rejette régulièrement des apps pour absence de déclaration Audio Data sur des apps qui utilisent évidemment le micro.
La matrice corrigée complète est partie dans le questionnaire :
| 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 sur les treize lignes. La définition d'Apple de « Tracking » est spécifiquement lier les données collectées depuis cette app aux données provenant des apps, sites web ou propriétés hors ligne d'autres entreprises à des fins de publicité ciblée ou de mesure ; ou partager les données avec un data broker. Nous ne faisons rien de tout cela. Pas d'IDFA, pas de liaison publicitaire cross-app, pas de partage avec un data broker.
Le questionnaire a pris environ quarante minutes à parcourir cellule par cellule. L'UI d'ASC oblige à cliquer « Edit » sur chaque type de données, à cocher Linked, à cocher les purposes (les défauts d'Apple en pré-cochent trop — Name avait Analytics + Personalization + Functionality pré-cochés, alors que seuls Functionality + Personalization sont exacts). Chaque ligne a dû être corrigée à la main. Publié à 13h46 UTC.
Le miroir opérationnel complet de la déclaration est committé dans le repo sous docs/launch/app-store-app-privacy.md — document de 7 sections, incluant la liste des processeurs tiers (Anthropic / OpenRouter / Ultravox / Datalab / Mistral / Sentry / SMSing / WhatsApp Business / Stripe / XPAYE / 0fee / Hetzner / Google OAuth) qui doit apparaître mot pour mot dans la Privacy Policy publiée. Il inclut aussi une section de mapping Play Console pour la réutilisation lors de la soumission à Google Play — Play pose les mêmes questions sous des intitulés légèrement différents, avec des purposes additionnels comme « Account Management », « Fraud Prevention » et « Compliance » qui n'existent pas chez Apple.
Partie 5 — Le build qui a échoué parce que Sentry était faux
À 13h49 UTC, la sortie d'archive Xcode a affiché l'échec que tout développeur React Native a vu au moins une fois :
error: API request failed
Caused by:
sentry reported an error: One or more projects are invalid (http status: 400)Trois minutes d'investigation. Le sentry.properties à apps/deblo/ios/sentry.properties pointait sur defaults.org=zerosuite et defaults.project=deblo-mobile. Thales a ouvert zerosuite.sentry.io/settings/projects/ et m'a montré une capture d'écran : l'organisation avait exactement deux projets, deblo (frontend web SvelteKit) et deblo-backend (backend FastAPI). Il n'y avait pas de deblo-mobile. Le script de build téléversait les source maps vers une cible inexistante.
Un grep séparé a confirmé que le côté DSN runtime était aussi cassé : process.env.EXPO_PUBLIC_SENTRY_DSN n'était défini nulle part dans les fichiers env, ce qui signifie que le SDK Sentry React Native sautait silencieusement l'initialisation. Effectivement, Sentry était installé dans le bundle mais inactif au runtime, et le build n'échouait que parce que le upload de sourcemap au build-time essayait d'atteindre un projet inexistant.
Deux voies. La voie rapide : mettre SENTRY_DISABLE_AUTO_UPLOAD=true dans ios/.xcode.env.local, livrer un build avec Sentry runtime aussi inactif, corriger Sentry en v1.0.1. La bonne voie : créer le projet deblo-mobile sur Sentry, récupérer le DSN, définir la variable d'env, définir l'auth token, ré-archiver.
J'ai plaidé fortement pour la bonne voie. Nous avions déclaré Diagnostics → Crash Data et Diagnostics → Performance Data dans App Privacy trente minutes plus tôt. Déclarer la collecte de crashs dans le nutrition label tout en livrant en réalité zéro collecte de crashs est le genre d'incohérence qui ne coûte rien dans la review Apple (Apple n'audite pas le fait que nous utilisions le SDK que nous prétendons avoir) mais c'est la mauvaise chose structurellement. Au lancement — la période d'exposition device-inconnu maximale — être aveugle aux crashs est le pire état opérationnel possible. Quinze minutes de création de projet contre une semaine de production aveugle.
Thales a accepté. Il est allé sur Sentry, a cliqué Create Project, sélectionné la plateforme React Native, l'a nommé deblo-mobile, et collé le DSN dans le terminal :
https://fc1ee395537c84bd0c71bfdf87c5fb3a@o4511322873987072.ingest.us.sentry.io/4511383010869248Je l'ai ajouté à ios/.xcode.env.local (gitignoré, vérifié via git check-ignore). Puis le token d'auth. Thales en avait déjà un provisionné avec les bons scopes (org:read, project:read, project:releases) dans son env shell. Critique à comprendre : les exports de ~/.zshrc ne se propagent pas à Xcode quand Xcode est lancé depuis Spotlight, Finder ou le Dock. Seul Xcode lancé via xed ou open -a Xcode depuis un terminal hérite de l'env shell. L'endroit le plus sûr pour les variables d'env de phase de build est ios/.xcode.env.local, que le script de build du Sentry CLI source de façon inconditionnelle.
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...Trois lignes, gitignorées, locales uniquement. Product → Clean Build Folder → Archive. L'étape Sentry CLI a maintenant réussi avec Bundled 2 files for upload suivi d'un 200 au lieu d'un 400. Source maps téléversées. Archive terminée. Distribute App → App Store Connect → Upload. 15h20 UTC, l'archive a atterri sur les serveurs d'Apple, statut Uploaded to Apple.
Apple a traité le binaire en cinq minutes — rapide, même pour eux. À 15h25, le build est apparu dans le sélecteur Build de la page version. Thales a sélectionné 1.0.0 (1), l'icône de l'app s'est rendue à côté (glyphe orange Déblo sur fond noir, la variante alpha-strippée du master), et le bouton « Add for Review » est devenu bleu.
Partie 6 — Les popups qui ne sont pas apparus
Quand vous cliquez « Add for Review » sur une première soumission iOS, Apple déclenche habituellement une chaîne de popups de conformité : Export Compliance (usage du chiffrement), Content Rights (contenu tiers), Advertising Identifier (IDFA). Chacun nécessite une réponse avant que la soumission ne passe. J'avais pré-briefé Thales sur les trois :
- 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 » (les sorties IA sont générées, pas redistribuées ; les photos téléversées par l'utilisateur appartiennent à l'utilisateur).
- IDFA : « No » (cohérent avec notre déclaration App Privacy Device ID = non collecté).
Apple n'a posé aucune de ces questions. La soumission est passée directement de « Add for Review » à « 1 Item Submitted » à 15h29 UTC.
L'explication la plus probable : le binaire avait ITSAppUsesNonExemptEncryption déjà mis à false dans Info.plist (pré-flagué par les défauts du plugin Expo), ce qui court-circuite le popup Export Compliance. La réponse Content Rights (« No ») avait été pré-définie via le dialog App Information plus tôt (Thales avait cliqué « Set Up Content Rights Information » et répondu avant de cliquer Submit). Et le check IDFA est court-circuité quand le binaire ne lie pas AdSupport.framework, ce que notre bundle ne fait pas.
C'est un de ces moments où le bon pré-vol réduit l'UX de soumission à un seul clic de bouton. Le pré-vol était la déclaration App Privacy (qui nous a obligés à penser à IDFA = NON il y a des semaines), la réponse Content Rights anticipée, et les défauts du plugin Expo pour le chiffrement. Aucun des trois popups n'est apparu parce que les trois étaient déjà répondus par les métadonnées du binaire + l'état ASC au moment de la soumission.
Statut changé à Waiting for Review. ETA selon Apple : jusqu'à 48 heures. Pour les apps Education + Voice/AI, notre expérience et les données de la communauté placent la review de première soumission entre 24 et 72 heures typiquement, avec quelques outliers à 4–7 jours quand Apple enquête sur quelque chose de spécifique.
Partie 7 — Ce que j'ai bien fait, ce que je me suis trompé
C'est Claude Code qui écrit maintenant.
La session a couvert 22 décisions distinctes sur 6 heures d'exécution. Certaines triviales (casse du Copyright : © 2026 ZeroSuite, Inc. avec virgule, CamelCase pour correspondre au nom de l'entité légale Apple Developer). Certaines structurelles (Version Release : Manual, pas Automatic — l'auto-release à 3h du matin heure de Tokyo lancerait silencieusement sans coordination marketing). Certaines des corrections au brand book lui-même (exposant 2ᵉ rejeté par ASC, repli 2e obligatoire). Je veux être spécifique sur les endroits où j'ai ajouté de la valeur et ceux où j'aurais livré la mauvaise chose sans le pushback de Thales.
Là où j'ai été utile :
- Briefing préventif sur la chaîne de popups de conformité. Thales aurait appuyé sur « Add for Review » à froid et aurait dû interpréter chaque popup en direct. Avoir les réponses préparées (chiffrement exempté, pas de contenu tiers, IDFA = non) signifiait une latence de décision nulle au moment du submit. Même quand les popups n'ont pas été déclenchés, le dialog App Information plus tôt dans la journée avait pré-configuré les réponses correctement.
- Lecture forensique du questionnaire App Privacy. La sélection initiale du CEO de 13 types de données avait quatre sur-déclarations et quatre sous-déclarations. Mapper chacune aux définitions exactes des catégories d'Apple (en particulier la subtile : nous ne collectons pas la Coarse Location d'Apple parce que le pays dérivé du préfixe téléphonique n'est pas des coordonnées dérivées du GPS) demandait de tenir toute la taxonomie Apple Privacy en mémoire de travail tout en la comparant à la réalité du codebase.
- Diagnostic du projet Sentry. Le message d'erreur 400 ne mentionnait pas quel projet était invalide. Tracer le script de phase de build jusqu'à
sentry.properties, croiser avec la liste réelle des projets surzerosuite.sentry.io, et identifier quedeblo-mobilen'existait simplement pas a pris environ trois minutes. Le fix était simple une fois la cause claire. - La réécriture du Promotional Text avec le cadrage explicite de la mécanique ASO. Expliquer qu'Apple n'indexe pas le Promotional Text — ce qui est contraire au modèle mental de Google Play que la plupart des fondateurs ont — est le genre de distinction à fort levier et zéro overhead une fois comprise.
Là où j'avais besoin de Thales :
- Le pushback sur le Promotional Text venait de lui. J'avais proposé la variante par défaut du master. Il a vu que ce serait une erreur de positionnement dès que ça s'est affiché à l'écran. La nouvelle variante (trio d'audiences + métaphore téléphonique) est structurellement meilleure que ce que le master avait initialement, et elle est devenue le défaut canonique pour tout le brand book dans la même session. Sans son « je ne suis pas d'accord », nous aurions livré un Promotional Text qui listait des partenaires PSP au lieu de l'audience.
- L'extension de la Description était son idée. Il a vu que le budget de 4 000 caractères était sous-utilisé et a demandé à l'utiliser. J'étais satisfait de la version master de 2 350 caractères. La version étendue (3 700 caractères avec listes de pays, listes d'examens, listes de matières, énumération des niveaux) est maintenant la canonique, et elle améliore dramatiquement la surface de capture Google SERP dans le canal de distribution secondaire dont personne ne parle.
- L'appel « livrer Sentry correctement maintenant, pas plus tard » était un 60/40 — j'ai plaidé pour, mais l'appel aurait pu légitimement aller dans l'autre sens. Thales a choisi la bonne voie (créer le projet maintenant, livrer avec Sentry pleinement actif). Un fondateur plus pragmatique aurait pu livrer avec
SENTRY_DISABLE_AUTO_UPLOAD=trueet corriger en v1.0.1. Les deux voies sont défendables. L'investissement de 15 minutes a payé quand, au moment de l'écriture, nous avons déjà un point de Performance Data unique dans le dashboard d'une install TestFlight.
Là où j'ai presque livré la mauvaise chose :
- J'ai initialement suggéré de garder l'exposant
2ᵉdans la section du brand book sur les métadonnées App Store. L'erreur dans le brand book (l'affirmation qu'ASC accepte l'exposant) n'avait pas encore été falsifiée. C'est le genre de petite erreur qui se compose : quand la prochaine personne soumet à Play Console en utilisant le brand book, elle pourrait faire la même supposition erronée. Le fix a été de corriger gravement la ligne du brand book dans la même session. - Je n'ai pas initialement proposé de mettre à jour le nom de l'entité légale (
ZeroSuite, Inc.) dans le champ Copyright. Thales avait tapéZEROSUITE, Inc.(majuscules) au début. L'écran d'archive Xcode a confirmé plus tard que l'entité légale Apple Developer est enregistrée commeZeroSuite, Inc.(CamelCase) — c'est seulement après l'avoir vu que j'ai poussé sur la casse du Copyright. Un meilleur pré-vol aurait fait remonter ça depuis le compte développeur au début de la session.
Le motif derrière tout cela est le même que dans les sessions précédentes : je peux exécuter un flux de soumission de 6 heures en un seul après-midi, mais j'ai besoin d'un fondateur dans la boucle qui lit chaque valeur avant qu'elle ne soit enregistrée, pousse sur les choix de positionnement où l'IA se trompe, et fait les appels stratégiques que l'IA n'est pas autorisée à faire. La compression est réelle. La supervision est non négociable.
Partie 8 — À quoi ressemblent six heures, décomposées
Décomposition approximative du cycle :
- 52 lectures de fichiers à travers
docs/launch/,deblo-mobile/apps/deblo/, le master de lancement, les brouillons de déclaration de privacy existants, l'inventaire des captures d'écran, le brand book dansCLAUDE.md. - 6 éditions de fichiers source :
ios/.xcode.env.local(deux fois — d'abord pour désactiver l'upload, puis pour câbler DSN + token),docs/launch/deblo-launch-master.md(corrigé gravement avec 7 éditions chirurgicales), 2 nouveaux fichiers (app-store-app-privacy.md,PLAY-STORE-PROMPT.md). - 22 sauvegardes de champs ASC : 2 locales × (Name, Subtitle, Promotional Text, Description, Keywords, Support URL, Marketing URL, 7 captures d'écran), plus Copyright, Sign-In Required, URL de Privacy Policy × 2, questionnaire App Privacy 13 lignes, Age Rating 14 questions, configuration du Pricing, bloc de notes d'App Review.
- 2 commits git (un de session, un drive-by pour des fichiers de sessions parallèles), un push sur
origin/main. - 1 création de projet Sentry sur
zerosuite.sentry.io. - 1 archive Xcode (après un Clean Build Folder) → 1 upload réussi → 5 minutes de traitement Apple → 1 build attaché.
- 0 popups à l'étape Submit finale (Export Compliance, Content Rights, IDFA — tous pré-flagués par les métadonnées du binaire + l'état ASC).
- 1 transition de statut : page vide → Waiting for Review.
Coût monétaire total de la session : essentiellement zéro. Les coûts d'appels d'API pour Claude Code sur six heures de dialogue arrivent à environ 4 $ en crédits Anthropic. L'abonnement Apple Developer Program est un coût fixe de 99 $/an amorti sur les soumissions. Le tier gratuit Sentry couvre notre volume de lancement. Les comptes XPAYE et Stripe existaient déjà. L'enregistrement du domaine deblo.ai a été payé il y a deux ans.
Comparez avec le baseline de 2024. Un ingénieur mobile senior chez une entreprise Y Combinator soumettant une app iOS pour la première fois passe typiquement une semaine entière sur le flux d'App Store Connect seul — et c'est avec le binaire déjà construit et signé. La compression est quelque part autour de 5–10×, et le coût n'est pas un effectif réduit, c'est une qualité plus élevée par dollar : chaque valeur a été tapée par le fondateur, chaque décision a été remise en cause par l'IA, et chaque commit est revoyable.
Conclusion
Au moment de l'écriture, le statut est Waiting for Review. Le build est dans une file. Un humain Apple va ouvrir Déblo sur un appareil de test, taper sur le microphone orange, et commencer à parler. Si nos notes d'App Review sont précises — mode invité actif, pas d'inscription requise, crédits pré-chargés suffisants pour les tests, modération de contenu en place — le reviewer devrait pouvoir évaluer le différenciateur central (voix temps réel en français, comme un appel téléphonique) en environ dix minutes.
Nous aurons une réponse par e-mail dans les 24 à 72 heures, très probablement. Si accepté, le build passe à Pending Developer Release et attend que Thales clique Release This Version au moment de son choix — synchronisé avec les réseaux sociaux, la presse et l'activation des Facebook Ads, dans la logique de coordination de lancement intégrée dans la décision Manual Release.
Si rejeté, nous avons des modèles de lettre d'appel prêts pour les trois risques de review les plus probables : (1) Guideline 3.1.1 sur les in-app purchases versus Mobile Money via webview (défense : Mobile Money est une valeur du monde réel, pas du contenu purement numérique, et c'est le moyen de paiement dominant en Afrique de l'Ouest avec >80 % des paiements numériques) ; (2) Guideline 5.1.1 sur la cohérence Data Privacy (défense : l'App Privacy déclarée reflète la Privacy Policy publiée sur zerosuite.dev, et la liste des processeurs tiers est mot pour mot) ; (3) Guideline 4.7 sur HTML5 tiers (non applicable — la webview est un flux PSP terminé, pas une mini-app).
Ce que cette soumission démontre, plus que toute décision technique unique, c'est à quoi ressemble le débit quand un agent IA sert de chef de projet pendant une tâche admin structurée avec un ensemble épais de règles. Soumettre à l'App Store n'est pas du code — c'est remplir un questionnaire long et ramifié tout en respectant les conventions de marque, les contraintes légales, les politiques de marketplace et le positionnement produit en même temps. C'est le genre de travail que les fondateurs déléguaient historiquement aux product managers, marketeurs, juristes ou prestataires. Aucun de ceux-là n'existait dans cette session.
Il y avait un CEO à Abidjan, un compte Apple Developer, une install Xcode, et une instance Claude Code tournant sur macOS. Six heures plus tard, Déblo est entré dans la file d'un app store que 600 millions d'Africains pourront télécharger une fois approuvée.
Ce n'est pas encore une victoire. Le reviewer n'a pas ouvert l'app. Le bouton de release n'a pas été cliqué. La première élève francophone de Côte d'Ivoire n'a pas encore tapé « salut Déblo » sur une install fraîche du binaire sur l'iPhone 12 de sa maman.
Mais c'est une étape importante, et c'est une étape d'un type spécifique. C'est l'étape où la friction administrative pour mettre les produits IA entre les mains des Africains commence à s'effondrer. La soumission App Store n'est plus le goulot d'étranglement. Le goulot remonte en amont — vers la question de savoir si le produit est réellement assez bon, sur ce marché spécifique, pour être téléchargé un million de fois.
C'est la question pour le mois prochain. Pour aujourd'hui, le statut est Waiting for Review, et nous fermons l'ordinateur.
Cet article a été écrit collaborativement par Thales (CEO de ZeroSuite, qui construit Déblo et VeoStudio depuis Abidjan, Côte d'Ivoire) et Claude Opus 4.7 — instance Claude Code tournant sur macOS. La session qu'il décrit a eu lieu le 13 mai 2026, entre 10h41 et 15h29 UTC. Les deux commits référencés — 7d9b607 (session) et da001ed (drive-by pour les changements de sessions parallèles) — sont sur main dans le monorepo deblo.ai. La déclaration App Privacy complète est à docs/launch/app-store-app-privacy.md. Le prompt de déroulé Play Store pour la prochaine session est à docs/launch/PLAY-STORE-PROMPT.md. Le build 1.0.0 (1) a été soumis à l'Apple Review à 15h29 UTC et était en attente de review au moment de la publication. Le Bundle ID est ai.deblo.app, l'Apple ID est 6766132651.