Antigravity: Mobile Native Readiness Design Pack¶
This design pack serves as the migration blueprint and contract bridge from the current iPhone Web/PWA implementation (frontend-core) to future native iOS (Swift/SwiftUI) clients.
Its goal is to enable future developers to implement native mobile client capabilities without requiring initial exploratory implementation on the Swift side. This guarantees that all platform schemas, design tokens, stream lifecycles, and offline-first state machines remain fully aligned across web and native boundaries.
Wave 1: Web-to-Native Surface Inventory¶
This section inventories the mobile UI surfaces from the iPhone Web/PWA client and specifies their native Swift equivalents, data dependencies, and interaction behavior.
| Web/PWA Surface | SwiftUI Native Equivalent | Data Dependencies (BFF API) | Stream Dependencies (SSE) | Gestures & Affordances | Offline/Cache Strategy | Contract Source |
|---|---|---|---|---|---|---|
| App Shell | TabView navigation structure |
/api/session (User auth metadata) |
N/A | Bottom bar tab selections | Stored profile metadata | MobileAppShell.api.ts |
| Summary Cards | RoundedRectangle cards with custom spacing |
/api/mobile/summaries |
/api/mobile/streams/inbox/sse |
Tap to expand; Long-press to inspect metadata | Cache via SwiftData; read-through sync | MobileSummaryCard.api.ts |
| Review Queue | List with swipeActions |
/api/fleet/decisions |
/api/fleet/missions/sse |
Swipe-left (Approve), Swipe-right (Hold) | Local queue staging; sync on reconnect | MobileReviewQueue.api.ts |
| Evidence Sheet | Custom SwiftUI View inside a .sheet(isPresented:) with detents |
/api/admin/evidence |
N/A | Drag-to-dismiss; Tap links to open source | Read-only; cached on initial load | MobileViewportEvidenceCard.api.ts |
| Journey Compact | Horizontal ScrollView + connection shapes |
/api/fleet/journeys |
/api/fleet/missions/sse |
Horizontal swipe scroll; Tap step for tooltip | Stale-while-revalidate | MobileJourneyCompact.api.ts |
| Stream Status | Scrollable LazyVStack log stream |
/api/mobile/streams |
/api/mobile/streams/[id]/sse |
Tap to pause stream; drag to scrub timeline | Local ring-buffer cache | MobileStreamStatus.api.ts |
| Diagnostics | Grouped List sections with disclosure indicators |
/api/fleet/status |
/api/fleet/status/sse |
Expand/Collapse section headers | Session-cached diagnostics report | MobileContractDiagnostics.api.ts |
| Rehearsal Lab | Vertical layout with transport controls | /api/mobile/rehearsals |
N/A | Tap pills (speed, scenario selection) | Pre-fetched local JSON fixtures | MobileRehearsalLab.api.ts |
| Cutover Control Room | Grouped form views with secure toggles | /api/fleet/config |
N/A | Biometric check before critical toggles | Local-only settings cache | MobileCutoverControlRoom.api.ts |
| Failure Gauntlet | Simulated state banner overlay panels | N/A | N/A | Swipe-down to dismiss simulated error | Simulated offline queue storage | MobileFailureScenarioPanel.api.ts |
Wave 2: Swift Model Projection Plan¶
To preserve contract-first API boundaries, the core platform schemas from commons-core and component contracts from frontend-core must project into typed Swift data structures.
1. Codable Model Projections¶
- Mobile Summary: Maps mobile-summary.schema.json.
struct MobileSummary: Codable, Identifiable { let id: String let title: String let priority: Priority let status: Status let sufficiency: Double let generatedAt: Date enum Priority: String, Codable { case critical, high, medium, low } enum Status: String, Codable { case open, closed, archived } } - Mobile Stream Event: Maps mobile-stream-event.schema.json.
struct MobileStreamEvent: Codable, Identifiable { let id: String let sequenceNumber: Int let streamId: String let payloadType: String let payload: [String: String] let timestamp: Date }
2. Typings Projection Strategy¶
- Naming Conventions: Swift models will match the TypeScript type name in UpperCamelCase. Enums should utilize native
String-backed types conforming toString, Codable, CaseIterable. - Optional/Required Fields: Nullable fields in schemas map directly to Swift optionals (
Type?). Required fields must be non-optional to enforce type safety during decode. - Date & Time Handling: All timestamps inside payloads are ISO8601 strings. De-serialization should utilize
JSONDecoder.dateDecodingStrategy = .iso8601. - Security & Auth Metadata: Access tokens will be kept in memory and persisted inside the iOS Keychain Services wrapper (never in
UserDefaults).
Wave 3: Native Token Projection Plan¶
The brand style guide is governed by the FE-1 contract (design-tokens.json). We map these tokens directly into native SwiftUI styling constants:
1. Color Palette Map (Dark Default)¶
- Custom theme properties defined in OKLch/HEX map to SwiftUI
Colorassets: --ut-color-surface-bg(Primary dark background) $\rightarrow$Color("SurfaceBackground")$\rightarrow$#09090b(Zinc 950)--ut-color-surface-card(Secondary card panel) $\rightarrow$Color("SurfaceCard")$\rightarrow$#18181b(Zinc 900)--ut-color-surface-border(Grid lines / borders) $\rightarrow$Color("SurfaceBorder")$\rightarrow$#27272a(Zinc 800)--ut-color-brand-primary(Purple branding) $\rightarrow$Color("BrandPrimary")$\rightarrow$#7c3aed(Violet 600)--ut-color-status-success(Connection healthy) $\rightarrow$Color("StatusSuccess")$\rightarrow$#10b981(Emerald 500)--ut-color-status-warning(Degraded / drift) $\rightarrow$Color("StatusWarning")$\rightarrow$#f59e0b(Amber 500)--ut-color-status-danger(Offline / block) $\rightarrow$Color("StatusDanger")$\rightarrow$#ef4444(Red 500)
2. Spacing and Radius (Layout)¶
- Core layout alignments map as constants:
--ut-radius-2xl$\rightarrow$let cardCornerRadius: CGFloat = 16.0--ut-radius-md$\rightarrow$let buttonCornerRadius: CGFloat = 8.0--ut-spacing-4$\rightarrow$let defaultPadding: CGFloat = 16.0--ut-spacing-2$\rightarrow$let itemSpacing: CGFloat = 8.0
3. Typography & Accessibility Gaps¶
- Fonts should resolve via standard Dynamic Type custom configurations rather than hardcoded size scales, ensuring full accessibility compliance:
- Headers:
Font.custom("Outfit-Bold", size: 18, relativeTo: .headline) - Micro labels:
Font.custom("Inter-Regular", size: 10, relativeTo: .caption2).monospacedDigit() - Token Gaps: Linear gradients in HTML are translated using
LinearGradient(gradient: Gradient(colors: [...]), startPoint: .top, endPoint: .bottom).
Wave 4: Interaction Translation Guide¶
Translating mobile-web DOM patterns to responsive, native SwiftUI interactions:
- Bottom Bar Toolbar $\rightarrow$ TabView:
Web toolbar pills are replaced with a native
TabViewlayout, using default iOS tab items with SF Symbols (tabItem { Label("Cockpit", systemImage: "macwindow.on.rectangle") }). - Evidence Overlay $\rightarrow$ Medium Detent Sheet:
Web slides or drawers are replaced using native SwiftUI sheets with detent limits:
.sheet(isPresented: $showEvidence) { EvidenceView() .presentationDetents([.medium, .large]) .presentationDragIndicator(.visible) } - Offline Stream Replay $\rightarrow$ Timeline List:
Scrollable replay lists will leverage a custom
ScrollViewReaderto automatically snap the scroll frame to active event items when playback is running. - Biometric Auth Integration $\rightarrow$ LocalAuthentication:
Cutover configurations (e.g. initiating system rollout or compile trigger) require LocalAuthentication (
LAContext) evaluation to match web PWA security scopes.
Wave 5: Native Risk Register¶
Native iOS development introduces specific constraints not present in browser execution environments:
| Risk Category | Impact | Mitigation Strategy |
|---|---|---|
| SSE Backgrounding | Background task suspension by OS closes active server connections. | Handle client reconnection automatically on App Scene state transition (scenePhase == .active), executing synchronization catchups. |
| APNs vs Web Push | iOS native requires Apple Push Notification service certificates. | Scaffolds the APNs bridge inside our ios-deploy.yml and matches JSON envelopes. |
| Keychain Synchronization | Stale session authentication tokens can lead to continuous BFF API rejections. | Run verification queries on app start. Erase Keychain variables on 401 Unauthorized responses to force re-auth. |
| Offline Cache Bloat | Uncapped local logging of stream history records exhausts device storage. | Configure limits on SwiftData caches, purging logs older than 7 days during background maintenance tasks. |
Wave 6: Native Acceptance Contract¶
Before any future Swift codebase can be merged as production-ready, it must validate successfully against this parity contract:
1. Functional Parity Categories¶
- Visual Parity by Intent: View layout, fonts, and dark mode palette must match the OKLch tokens defined inside
design-tokens.jsonto preserve brand fidelity. - Contract Parity: Network requests and local database transactions must validate exactly against
commons-coreschema structures. - Lifecycle Parity: Connection retry intervals, failure gauntlets, and rollback displays must mirror the transition sequence defined inside MobileOfflineStateMachine.api.ts.
- Accessibility Parity: Touch targets must measure at least $44 \times 44$ points. Native views must support VoiceOver tags and dynamic font resizing.
- Privacy Parity: Telemetry tracking metrics must mask PII and encrypt sensitive tokens inside Keychain Storage.
2. Validation Suite Execution¶
- Future development branches must compile successfully on Xcode 15+ without deprecation warnings.
- All Swift models must pass decoding unit tests using local JSON fixtures matching the active hypergraph trace mock schemas.