Der Waechter brach bisher ab und legte dem Menschen einen Befehl vor. Jetzt bringt er den Klon selbst auf origin/main, solange das nachweislich verlustfrei ist: reiner Rueckstand wird vorgespult; Commits, die nur lokal liegen, deren Tree aber dem des gemeinsamen Vorfahren gleicht, tragen inhaltlich nichts bei und werden verworfen (Reflog haelt sie 90 Tage). Nur Commits, die auch den Inhalt aendern, fuehren weiterhin zum Abbruch mit beiden Wegen zur Wahl. Damit entfaellt die Vorbereitung vor einem Signierlauf vollstaendig - wichtig, weil die bisher dokumentierte Vorbereitung ausgerechnet `git pull` war, also genau der Befehl, der auf einem Klon von vor dem Rewrite die entfernten Commits zurueckgeholt haette. Fuenf Lagen gegen Wegwerf-Repositories geprueft: gleich, zurueck, inhaltslos voraus, echte ungepushte Arbeit, echte Divergenz. APPLE_DEV_BACKLOG.md, OFFEN.md und AGENTS.md (Abschnitt AJ) nachgezogen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
9.4 KiB
Apple Dev Backlog (DM360)
Alles, was einen Xcode-Lauf oder das Apple Developer Portal braucht, wird hier gesammelt - und nur hier.
Warum: ein Xcode-Lauf lohnt sich nicht für eine einzelne native Änderung. Er wird erst gestartet, wenn eine nennenswerte Menge zusammengekommen ist; die Entscheidung darüber trifft der Eigentümer, nicht eine Sitzung.
Arbeitsregel (verbindlich)
- Jede Aufgabe, die Xcode oder das Apple-Portal braucht, kommt in diese
Datei, in derselben Sitzung, in der sie auffällt - nicht in eine Notiz im
Bericht und nicht nur in
AGENTS.md. - Nichts davon wird von sich aus gestartet. Ein Xcode-Lauf ist eine Handlung des Eigentümers am Mac; eine Sitzung bereitet ihn vor und meldet, wenn sich genug angesammelt hat.
- Was ohne Xcode geht, gehört nicht hierher: Änderungen an der Oberfläche
der App reisen im OTA-Bündel (
@capgo/capacitor-updater), Änderungen am Panel und am Backend über die Selbstaktualisierung der Integration. Nur nativer Code, Plugins, Berechtigungen, Signatur und Auslieferungsweg brauchen einen Lauf. - Erledigtes wird nicht gelöscht, sondern nach unten unter „Erledigt" verschoben - mit der Fassung, in der es ausgeliefert wurde. Sonst wird dieselbe Frage in einem halben Jahr wieder aufgemacht.
Stand der ausgelieferten App
Gemessen am Artefakt companion-app/auslieferung/App.ipa, nicht aus dem
Gedächtnis (06.09.2026):
| Fassung | 2026.9.4.17 (Build 1), App und Erweiterung gleich |
| Bundle-ID | app.datametric360, Erweiterung app.datametric360.teilen |
| Profile | beide Ad Hoc, 2 Geräte, gültig bis 2027-08-29 |
| Berechtigungen | Standort, Kalender (beide Schlüssel), Kamera - alle vorhanden |
packageClassList |
6 Klassen - beide eigenen Plugins fehlen |
Zum Vergleich: das Repository steht auf 2026.9.6.5. Der Abstand ist kein
Rückstand - alles dazwischen war Oberfläche und Backend und reist über OTA. Was
wirklich auf einen Lauf wartet, steht unten.
Wie ein Lauf abläuft
Diese Datei ist die Übergabe. Wer am Mac sitzt - mit oder ohne Claude am
Xcode - braucht keine weitere: hier steht der Stand, der eine Befehl, und was
danach zu prüfen ist. AGENTS.md ist nur für das Warum nötig.
Vorher
Nichts vorzubereiten - auch kein git pull. Das Skript holt origin/main
selbst und bringt den Klon darauf, solange das nachweislich verlustfrei ist:
ein reiner Rückstand wird vorgespult, und Commits, die zwar nur lokal liegen,
gegenüber dem gemeinsamen Vorfahren aber keine einzige Datei ändern, werden
verworfen. Beides sagt es an; das Reflog hält Verworfenes noch 90 Tage.
Warum kein
git pull: am 07.09.2026 sind drei Commits am Ende vonmainentfernt und der Branch per Force-Push zurückgesetzt worden. Ein Klon von davor steht damit vororigin/main- dort wäregit pullgenau das Falsche: der Merge hängt die entfernten Commits wieder in die Historie, und der nächste Push stellte sie auf dem Server wieder her (er ginge sogar ohne--forcedurch). Genau diese Lage räumt das Skript von sich aus auf.
Ab hier entscheidet es nichts mehr allein: liegen lokale Commits, die auch den Inhalt ändern, bricht es ab und legt dir beide Wege vor (pushen oder verwerfen) - ungepushte Arbeit wirft es nie weg. Ein nicht sauberer Arbeitsbaum bricht den Lauf ebenfalls ab - er ist die Voraussetzung dafür, dass Zurechtrücken oben gefahrlos ist. Und ebenso bricht er ab, wenn das Zielgerät nicht im Team eingetragen ist („Your team has no devices"); das ist dann eine Portal-Sache, kein Projektfehler.
Der Lauf
bash companion-app/scripts/ios-signieren.sh
Ein Befehl, von jedem Verzeichnis im Repository aus. Er wechselt selbst nach
companion-app/ und erledigt der Reihe nach: Git-Stand prüfen, Webbündel bauen,
native Hülle synchronisieren, Standort-/Kalender-/Kamera-Berechtigung eintragen,
Share-Erweiterung einrichten, App-Symbol einspielen, Versionsnummern setzen,
Archiv bauen und signieren, .ipa exportieren, die fertige .ipa gegenlesen
und die Auslieferung über die Luft vorbereiten.
Die Fassung kommt aus custom_components/audi_dashboard/manifest.json - es
gibt nichts von Hand hochzuzählen. Beim Schreiben dieser Zeilen wäre das
2026.9.6.5.
Einmalig beim ersten Signieren: der Schlüsselbund fragt, ob codesign den
Schlüssel benutzen darf. „Immer erlauben" wählen, nicht „Erlauben" - ein
Archiv signiert über 25 Programmteile und fragte sonst jedes Mal erneut. Bleibt
der Lauf minutenlang beim Signieren stehen, wartet er auf genau diesen Dialog.
Danach
git add companion-app/auslieferung && git commit && git push
Das Telefon lädt die .ipa aus dem Repository - ohne diesen Push ändert sich
dort nichts. Danach in Safari auf dem Telefon öffnen (andere Browser reichen
itms-services:// nicht an das System weiter):
itms-services://?action=download-manifest&url=https://gitea.nothaft.cloud/paul/audi-app/raw/branch/main/companion-app/auslieferung/manifest.plist
Die Adresse trägt kein ?v= - ein zweites Fragezeichen zerlegt den
Parameter, und weil iOS die Rückfrage erst aus dem geladenen Manifest baut,
passiert dann sichtbar gar nichts (Abschnitt CK).
Zum Schluss die eine Prüfung, die kein Skript abnehmen kann - siehe Abschnitt C unten.
A. Wartet auf einen Xcode-Lauf
A1. Zwei eigene Plugins sind auf dem Telefon tot
Auswirkung: Zwischenablage und Kalendereintrag funktionieren nicht. Das ist die einzige Position mit sichtbarem Ausfall.
Capacitor 8 registriert ausschließlich, was in packageClassList der
capacitor.config.json im Bündel steht (CapacitorBridge.swift,
registerPlugins()). Diese Liste erzeugt cap sync aus den installierten
npm-Paketen - app-eigene Plugins sind keine. Beide Klassen liegen nachweislich
im Programm der ausgelieferten .ipa und werden trotzdem nie registriert.
Korrektur liegt im Repo (a99ae43): ios-teilen-einrichten.mjs trägt die
Klassen nach jedem cap sync nach und liest ihre Namen aus den Swift-Dateien
selbst, damit sie nicht an zwei Stellen gepflegt werden. ios-signieren.sh
bricht ab, wenn eine davon im fertigen Bündel fehlt.
Hintergrund vollständig: AGENTS.md, Abschnitt DH und CM.
A2. Installationslink ohne zweites Fragezeichen
ios-luftweg.sh hängte den Cache-Brecher ?v= auch an die Manifest-Adresse
innerhalb des itms-services-Links - damit steht dort ein zweites ?, der
Abruf scheitert, und weil iOS die Rückfrage erst aus dem geladenen Manifest
baut, passiert sichtbar gar nichts.
Korrektur liegt im Repo (6365136). Die bereits ausgelieferte
auslieferung/index.html wurde von Hand nachgezogen; das Skript zieht beim
nächsten Lauf nach. Hintergrund: AGENTS.md, Abschnitt CK.
B. Wartet auf das Apple Developer Portal
Derzeit nichts offen. App-Gruppe, beide App-IDs und die Gerätefreigabe sind eingerichtet (Abschnitt AK), die Profile laufen bis 2027-08-29.
Vorzumerken, aber noch lange hin:
- 2027-07-17 - das Entwicklerzertifikat läuft ab.
- 2027-08-29 - beide Bereitstellungsprofile laufen ab.
- Ein neues Gerät braucht eine Registrierung im Portal und frisch
ausgestellte Profile. Ein bereits ausgestelltes Profil erfährt von einem neuen
Gerät nichts - deshalb räumt
ios-signieren.shdie zwischengespeicherten Profile vor dem Bauen weg (Abschnitt AI).
C. Nach dem Lauf zu prüfen
Am fertigen Bündel, nicht am Projekt. Die Begründung steht in Abschnitt AK:
von fünf Fehlern der nativen Hülle haben vier einen erfolgreichen Archivlauf
erzeugt und sind erst am entpackten .ipa aufgefallen.
Das Skript prüft selbst und bricht ab, wenn etwas fehlt:
- Die Erweiterung hat ein echtes Programm.
- App und Erweiterung tragen dieselbe
CFBundleShortVersionStringund eine brauchbareCFBundleVersion(ohne die lehnt iOS die Installation der ganzen App ab - Abschnitt CD). - Die App-Gruppe steht in den Entitlements beider Ziele.
- Beide eigenen Plugin-Klassen stehen in
packageClassList.
Von Hand bleibt genau eine Prüfung - auf dem Gerät: einen Beleg über das Teilen-Blatt schicken, ein PDF aus der Zwischenablage einfügen, einen Kalendereintrag anlegen. Ob die Plugins registriert sind, sagt Punkt 4; ob sie tun, was sie sollen, sagt nur das Telefon.
Was der Lauf von selbst erledigt
Damit es niemand ein zweites Mal von Hand macht: ios-signieren.sh trägt bei
jedem Lauf Standort-, Kalender- und Kamera-Berechtigung ein, richtet die
Share-Erweiterung ein, spielt das App-Symbol ein und setzt die Versionsnummern
in beide Ziele. Das muss sein, weil companion-app/ios/ gitignored ist und von
npx cap add ios jederzeit neu erzeugt wird - alles, was man in Xcode
anklickt, wäre danach weg (Abschnitt AI).
Unvermeidlich von Hand bleiben: die einmalige Portal-Einrichtung, das
Schlüsselbund-„Immer erlauben" beim ersten Signieren, und git push der
fertigen .ipa, weil das Telefon sie aus dem Repository lädt.
Erledigt
| Fassung | Was |
|---|---|
| 2026.9.4.17 | Kamera-Berechtigung für den QR-Scanner |
| 2026.9.4.7 | CFBundleVersion in beiden Bündeln - die App war vorher nicht installierbar |
| 2026.9.4.5 | Versionsnummern von App und Erweiterung angeglichen |
| 2026.9.2.7 | Share-Erweiterung, Zwischenablage- und Kalender-Plugin gebaut und signiert |
| 2026.8.30.8 | Erste signierte .ipa, Luftweg über Gitea eingerichtet |