pageta-native/STATUS.md
Till JS 26675cc372 docs: Sortier-Fehler im Event-Log behoben — TestFlight-Release ausstehend
mana-swift-event-sync sortierte lokal emittierte Events vor den bereits
gesyncten (SwiftData/SQLite: NULL ist aufsteigend der kleinste Wert), womit
ArticleSaved beim Replay zuletzt gewann. Deshalb blieben aus dem Share-Sheet
gespeicherte Artikel dauerhaft auf ihrem Platzhalter stehen — 16 von 22
winfuture-Speicherungen in einer echten Datenbank, obwohl winfuture gar
keine Cookie-Wand hat.

Die App zieht das Paket über einen lokalen Pfad, der Fix ist also beim
nächsten Build drin. Der Build selbst ist am 27.07. nicht entstanden:
Xcodes Paketauflösung brach am Netz ab, und die Signierung braucht
interaktive Freigabe.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 16:46:42 +02:00

184 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# pageta-native — Status
Letzter Stand: **2026-07-27**.
> **2026-07-27 — Sortier-Fehler im Event-Log behoben (Release ausstehend):**
> `mana-swift-event-sync` sortierte lokal emittierte Events (noch ohne
> `sequenceNumber`) VOR den bereits gesyncten — SwiftData sortiert über
> SQLite, und dort ist `NULL` aufsteigend der kleinste Wert. Der Replay
> wandte damit `ArticleSaved` zuletzt an und überschrieb jede spätere
> Änderung.
>
> **Folge in der Praxis:** aus dem Share-Sheet gespeicherte Artikel blieben
> dauerhaft auf ihrem Platzhalter stehen (Host als Titel, leerer Text),
> obwohl `enrichPendingArticles()` sauber `ArticleEnriched` nachgeschickt
> hatte. In einer echten Datenbank 16 von 22 winfuture-Speicherungen — und
> winfuture hat gar keine Cookie-Wand, die Extraktion wäre durchgelaufen.
>
> Behoben in `libs/mana-swift-event-sync` (`EventStorage.sortRank`), vier
> Tests, 42/42 grün. Die App zieht das Paket über einen **lokalen Pfad**
> (`project.yml` → `../../../libs/mana-swift-event-sync`), der Fix ist also
> beim nächsten Build automatisch drin — **kein Versions-Bump nötig**.
>
> ⚠️ **Offen: TestFlight-Build.** In der Sitzung vom 27.07. nicht erzeugt —
> Xcodes Paketauflösung brach beim Klonen von `swift-nio`/`mlx-swift-lm`
> am Netz ab (`RPC failed; curl 18`), und die Signierung braucht ohnehin
> interaktive Freigabe. Bis zum Release bleibt der Fehler auf den Geräten.
> Die Web-Reparatur („Neu extrahieren") holt betroffene Altlasten
> inzwischen nach — siehe `pageta/web/docs/EXTRAKTION.md`.
> **2026-05-29 — Release-Härtung + iOS-Build-Triage:**
> Build-Stand unter Xcode 26.3 verifiziert (sauberes DerivedData):
> - **macOS:** ✅ `BUILD SUCCEEDED`, reproduzierbar.
> - **iOS Device / Archive** (`generic/platform=iOS`): ✅ `BUILD
> SUCCEEDED`. Das Macro-Plugin `MLXHuggingFaceMacros` (transitiv via
> `ManaLLM` → `mlx-swift-lm`) wird hier korrekt fürs **Host-Target**
> (`arm64-apple-macos`) gebaut. **TestFlight ist nicht blockiert** —
> Archives bauen fürs Device.
> - **iOS Simulator:** ❌ „malformed response" beim Laden von
> `MLXHuggingFaceMacros` (`GemmaBackend.swift:127`). Ursache ist eine
> **simulator-spezifische** Arch-Kollision auf Apple Silicon: Host
> (arm64 macOS) und Simulator (arm64 iOS-Sim) haben dieselbe Arch,
> der Plugin-Loader greift die Simulator-Binary. Betrifft **nur den
> lokalen Sim-Dev-Loop**, nicht Device/Archive/Release. Workaround
> bis upstream-Fix: auf Device/„My Mac"-Destination entwickeln.
>
> Die ältere Behauptung „iOS-Sim grün, 38/38 Tests" (2026-05-25) galt
> für die damalige Toolchain; mit Xcode 26.3 ist der Sim-Pfad gebrochen.
> `mlx-swift-lm @ branch:main` bleibt konventionsgemäß (dokumentiert in
> `mana-swift-llm/CLAUDE.md`); kein Pin nötig, da Release-Pfad grün.
>
> **Fertig:** Die im 2026-05-25-Eintrag als offen notierten Write-Pfade
> im Markierungen-Tab (Note/Color/Delete) verschlucken Fehler nicht mehr
> — `MarkierungenTabView` zeigt sie jetzt als Alert (`writeError`),
> analog zu Lese-Liste/Reader.
> **2026-05-25 — Event-Sync auf geteilte Lib `ManaEventSync` migriert:**
> Die hand-gebaute Plumbing (Envelope/JSONValue/ULID/JWT/Storage/HTTP/
> Engine/Crypto/Vault, 9 Dateien ~900 LOC) ist raus; pageta konsumiert
> jetzt `mana-swift-event-sync` (`../mana-swift-event-sync`). Domäne
> (EventPayloads/States/Reducers/Coordinator) bleibt. Der Coordinator
> baut Events via `engine.makeEnvelope` — **kein `currentUserId()` mehr**,
> die Engine besitzt die Identität (Vorbereitung für Local-First ohne
> Login, E-4.5). Store-Name `pageta-event-sync` + App-Group unverändert
> → bestehende lokale Daten intakt. iOS-Sim-Build + 38/38 Tests grün.
> Erst-Adopter der Lib; wordeck folgt.
> **2026-05-25 — Markieren-Redesign (Books-Stil) + Fehler sichtbar:**
> Auswahl im Reader öffnet jetzt eine schwebende Farb-Palette direkt an
> der Auswahl (`HighlightSelectionPalette`) statt Edit-Menü → Bottom-
> Sheet; System-Edit-Menü unterdrückt, „Kopieren" lebt in der Palette.
> Ursache für „Markieren tut nichts": Schreibfehler (typisch *nicht
> eingeloggt* / stale `softFirst`-Session) wurden in `loadState`
> geschrieben, dessen UI aber nur bei `article == nil` rendert → still
> verschluckt. `addHighlight` zeigt den Fehler jetzt als Alert. 38/38
> Tests grün, iOS-Sim-Build clean. Nicht-eingeloggt-Fall führt jetzt
> über `ManaAuthGate.require` direkt ins Login-Sheet und holt die
> Markierung nach erfolgreichem Login automatisch nach (Alert bleibt
> Fallback für Rest-Fehler / stale `.signedIn`-Session). **Offen:**
> Markieren ganz ohne Login (Local-First/anon, eigener Umbau); System-
> Menü-Suppression + Palette-Platzierung am Gerät verifizieren; übrige
> Write-Pfade (Note/Color/Status) verschlucken Fehler noch genauso.
## Phase
**π-0..π-9 + π-11 ✅** — App baut iOS-Sim warning-frei, 38/38 Tests
grün (28 alt + 10 EventSync-Reducer). User-owned-CRUD läuft seit π-11
gegen `sync2.mana.how` (Event-Sourcing); HTTP-only bleiben Feed,
Extract-Preview und Widget-Snapshot. Nur π-10 (ASC) offen.
> **2026-05-20 — Phase π-11 (Event-Sync-Migration):** Reagiert auf
> pageta-api G-3 (retired articles-route, 2026-05-19), die alle
> user-owned-Article-Routen mit 410 antwortet. Native-App spricht
> jetzt direkt mit `sync2.mana.how`, mit lokaler SwiftData-Projection
> + Outbox + 60s-Polling. Surface von `PagetaAPI` bleibt identisch —
> UI unverändert. Pattern 1:1 aus nutriphi-native ν-14, reduziert auf
> Article + Highlight (Preferences-Aggregate ist offen, sobald
> Onboarding-UI dafür landet).
>
> **Design-Fix nebenbei:** Listentitel auf `.primary` umgestellt
> (statt `PagetaTheme.foreground` = dunkles Sepia). Im iOS-Dark-Mode
> sahen die Titel sonst muddy-orange aus, weil der paper-Theme-
> Foreground gegen schwarzen System-Background gerendert wurde.
>
> **Offen:** macOS-Build hängt am Mac-Provisioning-Profile, das die
> `Associated-Domains`-Capability nicht hat (Apple-Dev-Portal-TODO,
> nicht code-bezogen). π-10 (ASC + TestFlight) noch offen.
- **π-0**: paper-Theme, ManaAuthGate (Cross-App-SSO `ev.mana.session`),
AppIcon (Eselsohr-Page), AASA auf pageta.com.
- **π-1**: Feed-Tab via GET /api/v1/feed.
- **π-2**: Lese-Liste-Tab mit Status-SegmentedControl + Swipe-Actions.
- **π-3**: Reader-Detail (Plain-Text-Spike), Auto-`unread→reading`.
- **π-4**: Highlights Paragraph-Granularität via Tool-Endpoint + Tag-Sheet.
- **π-5**: Universal Links + pageta:// scheme → Sheet mit Reader.
7 URL-Router-Tests (Drift-Guard gegen pageta.mana.how).
- **π-6**: ShareExt (URL → App-Group-Queue → Launch-Flush an pageta-api).
Pattern aus herbatrium-native η-8.3.
## Phasen-Roadmap
| Phase | Status | Inhalt |
|---|---|---|
| π-0 | ✅ 2026-05-18 | Repo-Skelett, Login, Theme, Tab-Placeholder |
| π-1 | ✅ 2026-05-18 | Feed-Tab mit Pull-to-Refresh aus `GET /api/v1/feed` |
| π-2 | ✅ 2026-05-18 | Lese-Liste-Tab mit Status-Filter aus `GET /api/v1/articles` |
| π-3 | ✅ 2026-05-18 | Reader-Detail (Plain-Text-Spike + Toolbar) — Risiko-Spike entschieden zugunsten Plain-Text |
| π-4 | ✅ 2026-05-18 | Highlights (Paragraph-Granularität, 4 Farben) + Tag-Sheet — via Tool-Endpoints |
| π-5 | ✅ 2026-05-18 | Universal Links (pageta.com/article/:id) + pageta:// scheme → Sheet mit Reader |
| π-6 | ✅ 2026-05-18 | ShareExt (URL → App-Group-Queue → Launch-Flush) |
| π-7 | ✅ 2026-05-18 | WidgetKit Small/Medium/Large (App-Group-Snapshot, pageta:// Deep-Link) |
| π-8 | ✅ 2026-05-18 | Spotlight-Index für saved Articles + AppShortcuts (OpenFeed, SaveURL) |
| π-9 | ✅ 2026-05-18 | macOS-Adapt (NavigationSplitView + Sidebar + ⌘R Refresh + SceneStorage-Persistence) |
| π-10 | offen | ASC + TestFlight |
| π-11 | ✅ 2026-05-20 | Event-Sync-Migration auf `sync2.mana.how` (Article + Highlight Aggregate) — nutriphi-ν-14-Pattern |
**MVP-Cut**: π-0..π-4 (App + Login + Feed + Lese-Liste + Reader mit
Highlights). Phase 2: π-5..π-10.
## Vollständiger Plan
[`../mana/docs/playbooks/PAGETA_NATIVE_GREENFIELD.md`](../mana/docs/playbooks/PAGETA_NATIVE_GREENFIELD.md).
## Server-Pre-Conditions (alle ✅ vor π-0)
- ✅ AASA live auf `pageta.com/.well-known/apple-app-site-association`
- ✅ Widget-Snapshot-Endpoint `GET /api/v1/snapshot/widget` (JWT-gated)
- ✅ Primary-Switch zu pageta.com (Manifest base_url + PAGETA_PUBLIC_URL env)
## Apple-Dev-Portal-TODO
Till's manuelle Aktion vor erstem TestFlight-Build:
- [ ] Bundle-ID `ev.mana.pageta` registrieren (Team QP3GLU8PH3)
- [ ] **Bundle-ID `ev.mana.pageta.share`** (ShareExt, π-6 live im Code)
- [ ] **Bundle-ID `ev.mana.pageta.widget`** (Widget, π-7 live im Code)
- [ ] App-Group `group.ev.mana.pageta` für App **+ ShareExt + Widget** aktivieren
- [ ] **Keychain-Sharing-Group `ev.mana.session`** (Cross-App-SSO mit
anderen mana-Apps — Eintrag muss exakt matchen, sonst OSStatus
-34018 errSecMissingEntitlement beim ersten Token-Write)
- [ ] Capabilities: Associated Domains, App Groups, Keychain Sharing
- [ ] ASC-App-Eintrag (kommt mit π-10)
## Offene Punkte
- **π-3 Iteration 2** (deferred): Plain-Text-Render ist brauchbar,
aber lässt Headings/Bilder/Quotes/Code-Blocks/Links flach werden.
Wenn echte Content-Strukturen wichtig werden, Server-Markdown-
Convert (`turndown`) im pageta-api ergänzen + Native via
swift-markdown rendern.
- **π-4 Iteration 2** (deferred): Echte Text-Selection statt
Paragraph-Granularität. Brauchst UITextView-Bridge oder iOS-18+
Selection-Hook. Hat aber UX-Kosten (Long-Press-Auswahl muss
zuverlässig sein). Aktuell ist Tap-on-Paragraph der pragmatische
Cut.
- **Tag-Read-back fehlt server-seitig**: pageta-api hat keinen
`GET /api/v1/articles/:id/tags` und kein `tags`-Field im
Article-DTO. Native kann Tags hinzufügen, sieht sie aber nicht.
Web hat das gleiche Manko.
- **FeedItem-Tap** triggert noch keinen Save-Flow. Aktuell ist Feed
read-only. Save-from-Feed als Sub-Sprint (kleines Feature, kein
eigener π).
- **Reading-Progress-Persistierung** nicht implementiert. Scroll-
Offset wird nicht zum Server zurückgesynct. Status wird beim Open
auf `reading` gesetzt, aber kein granular Progress-Tracking.