Tout est parti d’une demande apparemment simple : malgré toutes les bonnes choses qu’iOS possède déjà, Android devrait également les avoir, n’est-ce pas ? Si cette phrase est confiée à la gestion de projet traditionnelle, elle deviendra une rangée de Jira ; remis à cet objectif, il deviendra un terminal natif Ghostty, Mosh Real UDP, Pad grand écran, PiP, Widget, notifications, Google Play et RevenueCat - plus un canard qui apprend progressivement à regarder des captures d'écran, à ouvrir un navigateur, à vérifier 403 et à douter de ses propres preuves.
Android n'est pas iOS et porte un manteau vert
Le moyen le plus courant de commettre des erreurs dans ce que l'on appelle « l'adaptation d'iOS à Android » est de copier la capture d'écran de la page pixel par pixel. Ce qu'il faut vraiment migrer, c'est le contrat de produit : l'utilisateur ne peut saisir un caractère chinois qu'une seule fois sur le terminal distant ; SSH ne peut pas être déconnecté si le moteur de rendu échoue ; le nouveau cadre doit être vu au retour de l'arrière-plan ; le forfait en cours doit être reconnu pour la récupération de l'abonnement ; le Pad n’est pas un téléphone portable agrandi horizontalement.
Ainsi, chaque fonctionnalité est traduite en trois couches : sémantique partagée, mise en œuvre de la plateforme et limite des preuves. iOS peut utiliser sa propre primitive de fenêtre d'affichage et Android peut utiliser Ghostty ABI 3 ; mais "doigt pour parcourir l'historique plus ancien et cliquez pour revenir en direct" doit être cohérent.
flowchart LR
I["iOS a déjà la capacité"] --> C{"contrat de produit partagé"}
C --> A["Implémentation native d'Android"]
A --> D["Stratégie de différenciation des plateformes"]
D --> V["Trois appareils et vérification du service réel"]
V --> R{"Des preuves passées ?"}
R -- "Non" --> F["Localisez la cause profonde et affinez la réclamation"]
F --> V
R -- "Oui" --> S["Examen par mini-lots et soumission atomique"]
Entrez le contrat
La composition de l'IME reste locale et engagée une seule fois ; les touches physiques, Ctrl, Alt et le modificateur collant ne peuvent pas être sérialisés.
contrat de rendu
La cellule large, la sélection, l'instantané, le défilement et le curseur doivent être cohérents sur l'image réelle.
contrat échoué
GL ne parvient pas à couper xterm, mais le transport SSH, l'historique des anneaux et les entrées utilisateur restent vivants.
contrat commercial
Le paiement mensuel, le paiement annuel et la durée de vie sont cartographiés de manière cohérente dans Play et RevenueCat. Lorsque la configuration fait défaut, il vaut mieux ne pas vendre plutôt que de deviner le SKU.
Le multiplateforme ne consiste pas à « se ressembler », mais à « tenir la même promesse même en cas de problème ».
Laissez Ghostty échouer d'abord, puis laissez-le réussir
La première règle d'Android Ghostty est un peu contre-intuitive : ne commencez jamais avec optimisme . Les constantes synchrones sont toujours définies en premier sur `ok=false`. L'auto-test asynchrone doit prouver que le noyau natif, ABI, VT, EGL, le shader, le téléchargement de texture, le dessin et la relecture sont tous vrais avant de passer de xterm à Ghostty.
Cela évite la métaphysique mobile classique du « obscurcir d'abord et ensuite en parler » dans la première image. Il existe également une limite supérieure de 2,5 secondes pour la certification de santé : si le GPU veut vraiment entrer en méditation, l'utilisateur peut regarder le spinner pendant 2,5 secondes maximum, puis obtenir un xterm fonctionnel au lieu d'un blanc permanent de type Zen.
stateDiagram-v2
[*] --> Pending
Pending --> Ghostty: health proof succeeds before timeout
Pending --> Xterm: timeout or proof fails
Ghostty --> Xterm: runtime GL failure
Xterm --> StableSession: same transport and ring replay
Ghostty --> StableSession: native renderer active
StableSession --> [*]
note right of Ghostty
Native VT plus full GL path
end note
core.ok=true
gl.maxRgbDelta=2
$ printf '中文 😀 é'
中文 😀 é
renderer unhealthy
→ xterm fallback
$ echo STILL_ALIVE
STILL_ALIVE
Wi-Fi off
DURING_OK
Wi-Fi on
AFTER_OK
Le film terminal est une représentation de la restauration de l'article, et non l'image originale de l'arrière-plan de l'opération ; les marqueurs, les résultats et les limites proviennent de preuves d'équipement réelles.
Ces os durs qui s’assemblent « facilement »
Composition de la méthode de saisie, séquence de touches xterm, sélection tactile, copie ActionMode, défilement natif, compositeur d'arrière-plan, sonde PixelCopy, instantané du processeur, mode de mise au point du clavier Pad... chaque élément ressemble à P3 individuellement, mais lorsqu'il est empilé, il détermine "est-ce un terminal ou un rectangle noir clignotant".
Il y a une autorisation dans le navigateur, mais il n'y a pas de clé toute faite
Les autorisations de Play Console se trouvent dans le profil Chrome connecté ; le Playwright intégré a un profil propre et rien ne peut être vu ; Le CDP n'a pas encore été ouvert. La réponse la plus simple est « demander à l’utilisateur de le faire manuellement ». Goal a choisi une autre voie : découvrir d'abord quel contexte de navigateur dispose d'autorisations, puis compresser la participation des utilisateurs en un consentement nécessaire.
S'il n'y a pas de pont prêt à l'emploi, générez-en un dans le répertoire temporaire : SDK MCP + `chrome-devtools-mcp` + client léger stdio, puis utilisez PTY persistant pour envoyer en continu `instantané → clic → instantané`. Il n'est pas présenté comme une « capacité de plate-forme » et est nettoyé une fois terminé ; la conclusion véritablement réutilisable est un profil dédié, une liste d'autorisation d'origine, une version corrigée et une désensibilisation par défaut.
sequenceDiagram
actor U as utilisateur
participant A as Goal Agent
participant B as Chrome
participant G as gcloud
participant P as Play Publisher API
participant R as RevenueCat API
A->>B: Nous avons constaté qu'il existe déjà un état de connexion et un contexte de compte cible.
U->>B: Autoriser explicitement le débogage à distance
B-->>A: Contrôle de page CDP disponible
A->>G: Activez l'API et créez deux ensembles d'identités les moins privilégiées
A->>B: Lier les autorisations des applications dans la Play Console
A->>P: Créez un catalogue de manière idempotente et téléchargez l'AAB interne
A->>R: Créer une application Android et une cartographie des produits
P-->>A: état des traces et des artefacts
R-->>A: droit et statut de l'offre
A-->>U: Demander uniquement des faits commerciaux et des décisions de publication irréversibles
La capture d’écran est noire, n’écrivez pas encore d’éloge funèbre pour le GPU.
Le moment le plus dangereux pour la vérification d’un téléphone Android est celui où la première capture d’écran semble très convaincante. SurfaceView peut être complètement noir dans les captures d'écran du système ; La capture d'écran Xiaomi peut faire 0 octet ; screenrecord ne peut enregistrer que le monde sans couche matérielle. À l'inverse, lorsque le tmux distant voit le marqueur, cela prouve seulement que le transport est vivant, mais pas que le compositeur local l'a dessiné.
Par conséquent, les preuves sont conçues comme plusieurs oracles : marqueur unique, arborescence d'interface utilisateur, PixelCopy, raster CPU, PID, dumpsys, logcat et volet distant. Ils doivent se falsifier les uns les autres, pas s'aligner et applaudir.
flowchart TB
M["Injecter un marqueur unique"] --> U["Arborescence de l'interface utilisateur et état du contrôle"]
M --> X["Capture d'écran ou PixelCopy"]
M --> S["PID · dumpsys · logcat"]
M --> T["Statut SSH/Mosh/tmux distant"]
U --> C{"Plusieurs oracles sont-ils cohérents ?"}
X --> C
S --> C
T --> C
C -- "Non" --> A["Classification des artefacts de test"]
A --> N["Remplacez le nonce et l'oracle et réexécutez"]
N --> M
C -- "Oui" --> B["Écrire des conclusions limitées"]
| phénomène observé | Je suis presque arrivé à la mauvaise conclusion | Dernière preuve orthogonale utilisée |
|---|---|---|
| Capture d'écran du Pad tout noir | Le compositeur Ghostty se bloque à nouveau | PixelCopy + CPU bitmap + generation |
| le marqueur apparaît deux fois | La saisie exactement une fois échoue | Le nouveau nonce prouve que le lot de délai d'attente chevauche la réexécution |
| Wi-Fi déconnecté et restauré | Mosh termine son itinérance cross-NAT | Déclarez uniquement la même session à restaurer ; le véritable itinérance dépend de l'identité du réseau |
| Métro démarrage à froid ANR | Le délai de rendu de 2,5 secondes est bloqué | Aucune récurrence du démarrage à froid du bundle intégré/mis en cache |
La vérité sur « l’automatisation totale » : ce n’est pas qu’il n’y a personne, mais que les gens n’apparaissent que là où ils ont de la valeur
La durée logique du Goal est cette fois de 21 heures, 54 minutes et 42 secondes, mais la disponibilité de la machine est plus courte. Il ne s'agit pas d'un processus mystérieux qui insiste pour ne pas dormir, mais s'appuie sur Git, tmux, les outils d'interrogation, l'état du plan, le transfert de révision et l'état du système externe pour restaurer en permanence le contexte.
Les utilisateurs de ce cycle ont très peu de participation réelle : connectez-vous à RevenueCat, effectuez un petit nombre de clics dans la console de développement Chrome/Google qui doivent être confirmés par le titulaire du compte et donnez une autorisation explicite pour des actions irréversibles telles que commit/push. La découverte de l'état de connexion, la plupart des formulaires Play et la vérification des faits, l'ouverture de gcloud/autorisation, la génération d'API, la vérification de l'appareil, les tests d'achat/restauration, l'enregistrement de captures d'écran, la récupération et le tri des erreurs sont tous en boucle fermée par Goal lui-même.
flowchart TB
O["Objectif stable"] --> P["Plan d’étape et seuil de preuve"]
P --> G["Validation atomique Git"]
P --> T["tmux et outils interrogeables"]
P --> E["État de l’appareil et du service externe"]
P --> R["verdict d'un examinateur indépendant"]
G --> C["Continuer après le processus ou le changement de démarrage"]
T --> C
E --> C
R --> C
C --> P
Lisez d'abord la machine, puis écrivez le code
Le navigateur, la CLI, l'appareil, l'état de connexion, le contrat iOS existant et l'état sale de l'entrepôt sont tous identifiés en premier.
Garantissez d'abord une issue
Ghostty, Mosh, Billing et OTA/native skew définissent tous la direction de l'échec avant d'activer de nouvelles fonctionnalités.
Laissez les vrais appareils et services parler
Les tests connectés sont suivis de véritables couches SSH, UDP, FCM, Play, RevenueCat et Pixel.
Chaque ligne à risque passe individuellement par la sentinelle
Les P1/P2 ne sont pas en retard jusqu’au bout ; l'examinateur accepte le code, puis la preuve de l'appareil.
Soumission précise de la liste blanche
L'arborescence de travail parallèle n'est pas entraînée et les profils temporaires, les supports, les luminaires et les secrets sont nettoyés à temps.
Dix choses que la différence finale ne vous dit pas
Trouvez vous-même l'entrée d'autorisation
Déterminez quel compte peut fonctionner à partir du contexte Chrome existant au lieu d'obliger l'utilisateur à recompter l'environnement.
Si vous n'avez pas CDP, prenez d'abord une capture d'écran.
Lorsque la couche OS obtient le consentement, l'utilisateur n'effectue l'autorisation nécessaire qu'une seule fois, puis repasse à l'automatisation DOM.
Si vous manquez d'outils, fabriquez les plus petits outils
Génération sur site de MCP, catalogue Play, téléchargement AAB et rapprochement des clients RevenueCat.
Deux SA, pas de clé principale
La facturation et l'éditeur sont séparés, et les autorisations GCP IAM et Play App sont hiérarchiques.
Un échec forcé ne fera pas perdre la session
Le moteur de rendu plante et la surface est modifiée, tandis que le transport et l'historique continuent de fonctionner.
Si la vidéo est piratée, les preuves seront remplacées
N’utilisez pas une chaîne de collecte brisée pour tirer des conclusions sur un produit.
DEV Seam réussit à ne pas contrefaire les produits
L'injection de débogage passe toujours par le gestionnaire de produit/la porte native, et DEV Pro est acheté de manière inappropriée comme preuve.
Affiner activement la déclaration
La récupération Wi-Fi est une récupération et non une usurpation d'identité d'une itinérance NAT différente.
Le nettoyage, c’est aussi une prestation
Les captures d'écran, les vidéos, les profils, les appareils, la base de données, la rotation et les états de la méthode de saisie sont restaurés.
Rendre la complexité réutilisable
Les analyses JSONL, CDP, les preuves de périphériques, le bootstrap Play/RC sont tous précipités dans des manuels.
Que peut-on copier directement depuis la prochaine application ?
Goal-driven Porting, v1
- Lorsque vous rédigez un contrat, n’écrivez pas « Faites comme iOS ». Clarifiez le succès, l’échec, le repli et la sémantique visible par l’utilisateur.
- Trouvez d’abord l’autorité. Qui a le dernier mot sur l'état de connexion du navigateur, Cloud IAM, les autorisations de stockage, les appareils et les services.
- Premier échec de fermeture. Les nouveaux biais natifs, de facturation et OTA doivent avoir d’anciens chemins qui peuvent fonctionner.
- Si vous manquez d'outils, réalisez des ponts fins. Seul le dernier kilomètre est résolu et le défaut est temporaire, observable et destructible.
- Testez l’équipement par hypothèse. Les émulateurs, les vieilles machines réelles et les grands écrans OEM ont tous leurs propres tâches, pas des jeux de quantité.
- Marqueur unique + plusieurs oracles. Le pixel, la structure, le système, le transport et l'extrémité distante doivent avoir au moins deux authentifications mutuelles.
- Considérez 4xx comme une carte. Portée, IAM, autorisation d'application, positionnement hiérarchique des autorisations de facturation.
- Chaque limite de danger est examinée individuellement. Fermez P1/P2 par petits lots et exécutez à nouveau le service réel.
- Présentez-vous lorsque vous avez besoin d’une vraie personne. Ce tour n'a en fait qu'une connexion, quelques clics de consentement/console et une autorisation d'effet secondaire git ; si d’autres projets impliquent une MFA, des faits juridiques ou une production, ces frontières irremplaçables seront laissées à d’autres.
- Nettoyez et notez les limites. Ne laissez pas de secrets, de montages, de « passes » exagérées et d'histoires héroïques irremplaçables.
La dernière conclusion contre-intuitive
L’histoire véritablement communicable de l’ingénierie de l’IA n’est pas « elle a fonctionné pendant 22 heures d’affilée », mais « elle savait quand le faire toute seule, quand rechercher des preuves, quand admettre que les captures d’écran ne sont pas dignes de confiance et quand demander aux gens de cliquer dessus ». La limite supérieure de l’automatisation n’est pas déterminée par le nombre de clics, mais par le sens des limites.
Le meilleur agent ne prend pas toutes les décisions à votre place ; cela réduit votre participation aux quelques moments où une décision est vraiment nécessaire.