DuckTerm Field Notes

A 21h 54m goal-driven engineering story

Von iOS-only zu Android-ready

Ein nahezu vollautomatisches, plattformübergreifendes Anpassungsexperiment: vom schwarzen Bildschirm von Ghostty, der Aphasie von Mosh bis hin zum Permission Detective von Chrome, der Google Play-Eintragung, dem geschlossenen Regelkreis des RevenueCat-Produkts und den drei Geräten, die sich gegenseitig „aussagen“.

  • Goal-driven
  • iOS → Android
  • Ghostty + Mosh
  • Play + RevenueCat
  • Evidence first
Cross-Bridge vom iOS-Terminal zum Android-Terminal Das Telefon links und das Tablet rechts sind durch eine Brücke aus Code, Tests und Beweisen verbunden. iOS / Ghostty $ ssh duck@host PARITY_READY scroll · ime · tui Android / Ghostty $ mosh duck@host SAME_SESSION_OK pixelcopy · pip · pad GOAL fail-closed first 403 ≠ Weltuntergang evidence or it didn’t happen
21h54mLogisches Ziel: Die benötigte Zeit ist nicht die Betriebszeit eines einzelnen Prozesses
4,441Werkzeugaufrufmuster, keine unabhängige Testnummer
3API35、Pixel API30、Xiaomi Pad
30/30Der endgültige Snapshot der verbundenen Suite wird nicht zum alten Snapshot hinzugefügt
259Visuelle Inspektionsaufrufe innerhalb des Zielfensters

Es begann mit einer scheinbar einfachen Bitte: Für all die guten Dinge, die iOS bereits hat, sollte Android sie auch haben, oder? Wenn dieser Satz dem traditionellen Projektmanagement übergeben wird, wird er zu einer Reihe von Jira; Wenn es diesem Ziel übergeben wird, wird es zu einem nativen Ghostty-Terminal, echtem Mosh-UDP, einem großen Pad-Bildschirm, PiP, Widget, Benachrichtigungen, Google Play und RevenueCat – und zu einer Ente, die nach und nach lernt, sich Screenshots anzusehen, einen Browser zu öffnen, 403 zu überprüfen und ihre eigenen Beweise anzuzweifeln.

01 / THE CONTRACT

Android ist kein iOS und trägt einen grünen Mantel

Der häufigste Fehler bei der sogenannten „Anpassung von iOS auf Android“ besteht darin, den Screenshot der Seite Pixel für Pixel zu kopieren. Was wirklich migriert werden muss, ist der Produktvertrag : Der Benutzer kann am entfernten Ende nur einmal ein chinesisches Zeichen eingeben; SSH kann nicht getrennt werden, wenn der Renderer ausfällt; der neue Rahmen muss beim Zurückkehren aus dem Hintergrund zu sehen sein; Der aktuelle Plan muss für die Wiederherstellung des Abonnements anerkannt werden. Das Pad ist kein Mobiltelefon, das horizontal vergrößert wird.

Daher wird jede Fähigkeit in drei Ebenen übersetzt: gemeinsame Semantik, Plattformimplementierung und Beweisgrenze. iOS kann sein eigenes Ansichtsfenster-Grundelement verwenden und Android kann Ghostty ABI 3 verwenden; aber „Finger nach unten, um den älteren Verlauf zu durchsuchen und klicken, um zum Leben zurückzukehren“ muss konsistent sein.

flowchart LR
  I["iOS verfügt bereits über die Möglichkeit"] --> C{"gemeinsamer Produktvertrag"}
  C --> A["Native Android-Implementierung"]
  A --> D["Strategie zur Plattformdifferenzierung"]
  D --> V["Drei Geräte und echte Serviceüberprüfung"]
  V --> R{"Beweise übergeben?"}
  R -- "NEIN" --> F["Finden Sie die Grundursache und grenzen Sie den Anspruch ein"]
  F --> V
  R -- "Ja" --> S["Mini-Batch-Überprüfung und atomare Einreichung"]
            
Abbildung 1: Anstatt die Implementierung zu kopieren, migrieren Sie den Vertrag. Bei einem Fehler kehrt die Version zur Verifizierungsschleife zurück, anstatt dass die Version „Sieht ungefähr gleich aus“ angezeigt wird.
⌨️

Geben Sie den Vertrag ein

Die IME-Komposition bleibt lokal und wird genau einmal festgeschrieben. Physische Tasten, Strg, Alt und Sticky-Modifikator können nicht serialisiert werden.

🖼️

Vertragserfüllung

Breite Zelle, Auswahl, Snapshot, Scrollback und Cursor müssen im realen Frame konsistent sein.

🛟

gescheiterter Vertrag

GL kann xterm nicht unterbrechen, aber SSH-Transport, Ringverlauf und Benutzereingaben bleiben bestehen.

💳

Geschäftsvertrag

Monatliche Zahlung, jährliche Zahlung und Laufzeit werden in Play und RevenueCat einheitlich abgebildet. Wenn es an Konfiguration mangelt, ist es besser, nicht zu verkaufen, als die SKU zu erraten.

Bei Cross-Plattform geht es nicht darum, „gleich auszusehen“, sondern darum, „das gleiche Versprechen zu halten, auch wenn etwas schief geht“.

02 / THE NATIVE LINE

Lassen Sie Ghostty zuerst scheitern und lassen Sie es dann erfolgreich sein

Die erste Regel von Android Ghostty ist etwas kontraintuitiv: Beginnen Sie niemals optimistisch . Synchrone Konstanten werden immer zuerst auf „ok=false“ gesetzt. Der asynchrone Selbsttest muss vor dem Wechsel von xterm zu Ghostty beweisen, dass nativer Kern, ABI, VT, EGL, Shader, Textur-Upload, Draw und Readback alle wahr sind.

Dies vermeidet die klassische mobile Metaphysik „erst abdunkeln und dann darüber reden“ im ersten Frame. Es gibt auch eine 2,5-Sekunden-Obergrenze für die Gesundheitszertifizierung: Wenn die GPU wirklich in die Meditation einsteigen möchte, kann der Benutzer bis zu 2,5 Sekunden lang dem Spinner zusehen und erhält dann ein funktionierendes xterm anstelle eines Zen-ähnlichen permanenten Blanks.

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
            
Abbildung 2: Renderer ist eine austauschbare Oberfläche, kein Transport. Auch wenn GL während des Betriebs ausfällt, wird die Sitzung fortgesetzt.
GHOSTTY_HEALTH
core.ok=true
gl.maxRgbDelta=2

$ printf '中文 😀 é'
中文 😀 é

same session
FORCED_GL_FAIL
renderer unhealthy
→ xterm fallback

$ echo STILL_ALIVE
STILL_ALIVE

connect count: 1
MOSH_ROAM
Wi-Fi off
DURING_OK
Wi-Fi on
AFTER_OK

same PID · same UDP

Der Endfilm ist eine Darstellung der Restaurierung des Artikels, nicht das Originalbild des Operationshintergrunds; Markierungen, Ergebnisse und Grenzen stammen aus echten Ausrüstungsnachweisen.

Diese harten Knochen, die sich „einfach“ zusammenfügen lassen

Zusammensetzung der Eingabemethode, xterm-Tastenfolge, Berührungsauswahl, ActionMode-Kopie, nativer Scrollback, Hintergrund-Compositor, PixelCopy-Sonde, CPU-Snapshot, Pad-Tastatur-Fokusmodus ... jedes Element sieht einzeln wie P3 aus, aber wenn es zusammengestapelt wird, bestimmt es, „ist dies ein Terminal oder ein blinkendes schwarzes Rechteck“.

03 / THE BROWSER DETECTIVE

Es liegt eine Berechtigung im Browser vor, es gibt jedoch keinen vorgefertigten Schlüssel

Die Berechtigungen der Play Console liegen im angemeldeten Chrome-Profil; der eingebaute Playwright ist ein sauberes Profil und es ist nichts zu sehen; CDP wurde noch nicht geöffnet. Die einfachste Antwort lautet: „Bitten Sie den Benutzer, dies manuell zu tun.“ Goal hat einen anderen Weg gewählt: Zuerst herausfinden, welcher Browserkontext Berechtigungen hat, und dann die Benutzerbeteiligung in eine notwendige Einwilligung komprimieren.

Detektivdiagramm für Browserberechtigungen Der Agent identifiziert die Chrome-Zustimmung anhand von Screenshots. Nach der Benutzerautorisierung übernimmt CDP die Seite und verbindet sich dann mit gcloud, Play API und RevenueCat. chrome:// remote debugging Remote-Debugging zulassen? Benutzer erlaubt CONTROL PLANE ✓ CDP snapshot + click ✓ gcloud API enablement ✓ Play publisher SA ✓ RevenueCat v2 secrets stay outside repo snapshot then click
Abbildung 3: CDP-Kontrollseite, kann das eigene Autorisierungs-Popup-Fenster nicht steuern. Screenshots und Betriebssystemautomatisierung sind für das Einholen der Einwilligung verantwortlich, und Benutzer sind für das Vertrauen verantwortlich.

Wenn es keine fertige Brücke gibt, generieren Sie eine im temporären Verzeichnis: MCP SDK + „chrome-devtools-mcp“ + Thin Stdio Client, und verwenden Sie dann persistentes PTY, um kontinuierlich „Schnappschuss → Klicken → Schnappschuss“ zu senden. Es ist nicht als „Plattformfähigkeit“ verpackt und wird nach der Fertigstellung bereinigt. Die wirklich wiederverwendbare Schlussfolgerung ist ein dediziertes Profil, eine Ursprungs-Zulassungsliste, eine feste Version und eine Standard-Desensibilisierung.

Ein praktischer Witz: 403 bedeutet nicht unbedingt, dass Google Sie nicht liebt. Es könnte sich um einen OAuth-Bereich, GCP IAM, Play App-Berechtigung, Abrechnungsberechtigung handeln oder die Berechtigung ist noch in Bearbeitung. Zuerst schichten und dann noch einmal versuchen; Benutzen Sie die Schaltfläche „Aktualisieren“ nicht als Rosenkranz.
sequenceDiagram
  actor U as Benutzer
  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: Es wurde festgestellt, dass bereits ein Anmeldestatus und ein Zielkontokontext vorhanden sind
  U->>B: Remote-Debugging ausdrücklich zulassen
  B-->>A: CDP-Seitensteuerung verfügbar
  A->>G: Aktivieren Sie die API und erstellen Sie zwei Sätze von Identitäten mit den geringsten Privilegien
  A->>B: Binden Sie App-Berechtigungen in der Play Console
  A->>P: Katalog idempotent erstellen und internes AAB hochladen
  A->>R: Erstellen Sie eine Android-App- und Produktzuordnung
  P-->>A: Track- und Artefaktstatus
  R-->>A: Berechtigungs- und Angebotsstatus
  A-->>U: Fordern Sie nur geschäftliche Fakten und unumkehrbare Freigabeentscheidungen an
            
Abbildung 4: Browser, Cloud IAM, Play-Berechtigungen und RevenueCat sind die vier Steuerungsebenen. Wenn Sie sie zu einem „Login Successful“ zusammenfassen, erhalten Sie nur mehr 403s.
04 / THE EVIDENCE LAB

Der Screenshot ist schwarz, schreiben Sie noch keine Lobrede auf die GPU.

Der gefährlichste Moment bei der Android-Telefonverifizierung ist, wenn der erste Screenshot sehr überzeugend aussieht. SurfaceView ist in System-Screenshots möglicherweise vollständig schwarz. Xiaomi-Screencap kann 0 Bytes groß sein; screenrecord darf nur die Welt ohne Hardwareschicht aufzeichnen. Wenn umgekehrt der entfernte tmux die Markierung sieht, beweist dies nur, dass der Transport aktiv ist, nicht jedoch, dass der lokale Compositor ihn gezeichnet hat.

Beweislabor mit drei Geräten Der API35-Emulator, Pixel 4 und Xiaomi Pad sind jeweils für die Überprüfung des neuen Systems, der realen Maschine des alten Systems und der OEM-Großbildschirmprüfung verantwortlich. API35 emulator Neuer API-Vertrag Pixel 4 API30 physical IME · FCM · SQLite Xiaomi Pad API33 · MIUI master detail Pad · Surface · rotation
Abbildung 5: Bei den drei Geräten handelt es sich nicht um denselben Test multipliziert mit drei, sondern um drei komplementäre Annahmen: neue API, alte echte Maschine und großer OEM-Bildschirm.

Daher sind die Beweise als mehrere Orakel konzipiert: eindeutiger Marker, UI-Baum, PixelCopy, CPU-Raster, PID, Dumpsys, Logcat und Remote Pane. Sie müssen sich gegenseitig verfälschen, dürfen sich nicht anstellen und applaudieren.

flowchart TB
  M["Injizieren Sie einen einzigartigen Marker"] --> U["UI-Baum und Kontrollstatus"]
  M --> X["Screenshot oder PixelCopy"]
  M --> S["PID · dumpsys · logcat"]
  M --> T["Remote-SSH/Mosh/tmux-Status"]
  U --> C{"Sind mehrere Orakel konsistent?"}
  X --> C
  S --> C
  T --> C
  C -- "NEIN" --> A["Testartefakte klassifizieren"]
  A --> N["Ersetzen Sie Nonce und Oracle und führen Sie es erneut aus"]
  N --> M
  C -- "Ja" --> B["Schreiben Sie begrenzte Schlussfolgerungen"]
            
Abbildung 6: Je mehr Beweise, desto besser, aber je unabhängiger die Quelle, desto besser. Wenn es einen Konflikt gibt, zweifeln Sie zuerst an der Sammelkette, dann am Produkt und auch an Ihrem ersten Urteil.
Phänomen gesehenBin fast zu dem falschen Schluss gekommenZuletzt verwendeter orthogonaler Beweis
Pad-Screenshot ganz schwarzGhostty Compositor hängt erneutPixelCopy + CPU bitmap + generation
Die Markierung erscheint zweimalDie Eingabe genau einmal schlägt fehlDie neue Nonce beweist, dass sich der Timeout-Batch mit der Wiederholung überschneidet
WLAN getrennt und wiederhergestelltMosh schließt Cross-NAT-Roaming abDeklarieren Sie nur, dass dieselbe Sitzung wiederhergestellt werden soll. Das tatsächliche Roaming hängt von der Netzwerkidentität ab
Metro-Kaltstart ANR2,5 Sekunden Renderer-Verzögerung bleibt hängenKein erneuter Kaltstart des eingebetteten/zwischengespeicherten Bundles
05 / THE LONG GOAL

Die Wahrheit über „Vollautomatisierung“: Es ist nicht so, dass es keine Menschen gibt, sondern dass Menschen nur dort auftauchen, wo sie wertvoll sind

Die logische Dauer des Ziels beträgt dieses Mal 21 Stunden, 54 Minuten und 42 Sekunden, die Maschinenverfügbarkeit ist jedoch kürzer. Es handelt sich nicht um einen mysteriösen Prozess, der darauf besteht, nicht zu schlafen, sondern auf Git, tmux, abfragbare Tools, Planstatus, Überprüfungsübergabe und externen Systemstatus angewiesen ist, um den Kontext kontinuierlich wiederherzustellen.

Benutzer in dieser Runde haben nur sehr wenig tatsächliche Beteiligung: Melden Sie sich bei RevenueCat an, führen Sie eine kleine Anzahl von Klicks in der Chrome-/Google-Entwicklerkonsole aus, die vom Kontoinhaber bestätigt werden müssen, und erteilen Sie explizite Genehmigungen für unumkehrbare Aktionen wie Commit/Push. Die Erkennung des Anmeldestatus, das Ausfüllen der meisten Play-Formulare und die Überprüfung von Fakten, das Öffnen von gcloud/Berechtigungen, die API-Generierung, die Geräteüberprüfung, Kauf-/Wiederherstellungstests, Screenshot-Aufzeichnung, Fehlerbeseitigung und -sortierung werden von Goal selbst in einem geschlossenen Regelkreis durchgeführt.

flowchart TB
  O["Stabiles Ziel"] --> P["Stufenplan und Evidenzschwelle"]
  P --> G["Git-Atom-Commit"]
  P --> T["tmux und abfragbare Tools"]
  P --> E["Geräte- und externer Dienststatus"]
  P --> R["Urteil eines unabhängigen Gutachters"]
  G --> C["Fahren Sie nach einer Prozess- oder Boot-Änderung fort"]
  T --> C
  E --> C
  R --> C
  C --> P
            
Abbildung 7: Die Beständigkeit eines langfristigen Ziels beruht auf einem wiederherstellbaren Zustand und nicht auf einem Prozess, der niemals beendet wird.

Lesen Sie zuerst die Maschine und schreiben Sie dann den Code

Zuerst werden der Browser, die CLI, das Gerät, der Anmeldestatus, der bestehende iOS-Vertrag und der Warehouse-Dirty-Status identifiziert.

Garantieren Sie zunächst einen Ausweg

Ghostty, Mosh, Billing und OTA/native Skew definieren alle die Fehlerrichtung, bevor neue Funktionen aktiviert werden.

Lassen Sie echte Geräte und Dienste sprechen

Auf verbundene Tests folgen echte SSH-, UDP-, FCM-, Play-, RevenueCat- und Pixel-Ebenen.

Jede Hochrisikolinie durchläuft den Sentinel einzeln

P1/P2 sind nicht bis zum Ende zurückgeblieben; Der Prüfer akzeptiert den Code und dann den Gerätenachweis.

Präzise Übermittlung der Whitelist

Der parallele Arbeitsbaum wird nicht mitgerissen und temporäre Profile, Medien, Vorrichtungen und Geheimnisse werden rechtzeitig bereinigt.

06 / THE SURPRISE LEDGER

Zehn Dinge, die Ihnen der letzte Unterschied nicht verrät

🕵️

Finden Sie selbst den Erlaubniseingang

Bestimmen Sie, welches Konto im vorhandenen Chrome-Kontext ausgeführt werden kann, anstatt dass der Benutzer die Umgebung erneut konten muss.

📸

Wenn Sie kein CDP haben, machen Sie zuerst einen Screenshot.

Wenn die Betriebssystemschicht die Zustimmung erreicht, führt der Benutzer die erforderliche Autorisierung nur einmal durch und wechselt dann zurück zur DOM-Automatisierung.

🧰

Wenn Ihnen Werkzeuge fehlen, stellen Sie die kleinsten Werkzeuge her

Vor-Ort-Generierung von MCP, Play-Katalog, AAB-Upload und RevenueCat-Abgleich von Kunden.

🔐

Zwei SAs, kein Hauptschlüssel

Abrechnung und Herausgeber sind getrennt und GCP IAM- und Play App-Berechtigungen sind hierarchisch.

🧯

Durch einen erzwungenen Fehler geht die Sitzung nicht verloren

Der Renderer stürzt ab und die Oberfläche wird verändert, während Transport und Verlauf weiterhin funktionieren.

🎞️

Wenn das Video gehackt wird, werden die Beweise ersetzt

Ziehen Sie aus einer unterbrochenen Sammelkette keine Rückschlüsse auf ein Produkt.

🧪

DEV Seam gelingt es, Produkte nicht zu fälschen

Die Debug-Injection läuft immer noch über den Produktmanager/natives Gate und DEV Pro wird fälschlicherweise als Beweis gekauft.

🧭

Grenzen Sie die Aussage aktiv ein

Bei der Wi-Fi-Wiederherstellung handelt es sich um eine Wiederherstellung, nicht um die Nachahmung eines anderen NAT-Roamings.

🧹

Auch die Reinigung liefert

Screenshots, Videos, Profile, Fixtures, DB, Rotation und Eingabemethodenzustände werden wiederhergestellt.

🪶

Komplexität wiederverwendbar machen

JSONL-Forensik, CDP, Gerätebeweis, Play/RC-Bootstrap sind alle in Handbüchern zusammengefasst.

07 / THE REUSABLE PLAYBOOK

Was kann direkt aus der nächsten App kopiert werden?

Goal-driven Porting, v1

  1. Wenn Sie einen Vertrag schreiben, schreiben Sie nicht „Machen Sie es wie iOS.“ Klären Sie Erfolg, Misserfolg, Fallback und für den Benutzer sichtbare Semantik.
  2. Finden Sie zuerst die Autorität. Wer hat das letzte Wort über den Browser-Anmeldestatus, Cloud IAM, Store-Berechtigungen, Geräte und Dienste?
  3. Erster Fail-Closed. Neue native, Abrechnungs- und OTA-Verzerrungen müssen über alte Pfade verfügen, die funktionieren können.
  4. Wenn Sie kein Werkzeug haben, machen Sie dünne Brücken. Nur die letzte Meile ist gelöst, und der Ausfall ist vorübergehend, beobachtbar und zerstörbar.
  5. Testen Sie die Ausrüstung anhand einer Hypothese. Emulatoren, alte echte Maschinen und OEM-Großbildschirme haben alle ihre eigenen Aufgaben, keine Massenspiele.
  6. Einzigartiger Marker + mehrere Orakel. Pixel, Struktur, System, Transport und Gegenstelle müssen über mindestens zwei gegenseitige Authentifizierungen verfügen.
  7. Stellen Sie sich 4xx als eine Karte vor. Umfang, IAM, App-Berechtigung, hierarchische Positionierung der Abrechnungsberechtigung.
  8. Jede Gefahrengrenze wird einzeln überprüft. Schließen Sie P1/P2 in kleinen Mengen und führen Sie den eigentlichen Dienst erneut aus.
  9. Erscheinen Sie, wenn Sie eine echte Person brauchen. In dieser Runde gibt es eigentlich nur Login, ein paar Zustimmungs-/Konsolenklicks und Git-Nebenwirkungsautorisierung; Wenn andere Projekte MFA, rechtliche Fakten oder Produktion betreffen, werden diese unersetzlichen Grenzen anderen überlassen.
  10. Räumen Sie auf und schreiben Sie die Grenzen auf. Hinterlassen Sie keine Geheimnisse, Spielpläne, übertriebenen „Pässe“ und unwiederholbaren Heldengeschichten.

Die letzte kontraintuitive Schlussfolgerung

Die wirklich mitteilbare Geschichte der KI-Technik lautet nicht: „Sie hat 22 Stunden am Stück funktioniert“, sondern „Sie wusste, wann sie es alleine machen musste, wann sie nach Beweisen suchen musste, wann sie zugeben musste, dass Screenshots nicht vertrauenswürdig sind, und wann sie die Leute dazu bringen musste, darauf zu klicken.“ Die Obergrenze der Automatisierung wird nicht durch die Anzahl der Klicks bestimmt, sondern durch das Gefühl der Grenzen.

Der beste Makler trifft nicht alle Entscheidungen für Sie; Dadurch wird Ihre Teilnahme auf die wenigen Male beschränkt, in denen eine Entscheidung wirklich erforderlich ist.