learning_ai_common_plat/docs/MOBILE_DRY_REFACTORING_ROADMAP.md
saravanakumardb1 76e05f836a docs: Update MOBILE_DRY_REFACTORING_ROADMAP with all 9 phases completed
Phases 1-9 complete with commit links and checked boxes:
- Phase 1: ChronoMind Android (2060a83)
- Phase 2: JarvisJr Android (336535a)
- Phase 3: FlowMonk Mobile RN (ce70d8c)
- Phase 4: LysnrAI Android (24a09a2) — 11 dead services deleted
- Phase 5: NomGap RN (63bd34b) — billingFetch replaced
- Phase 6: LysnrAI iOS (862e981) — 5 dead services deleted
- Phase 7: Auth App Android (5b65215) — telemetry/flags/killswitch added
- Phase 8: Auth App iOS (4a84050) — telemetry/flags/killswitch added
- Phase 9A: ChronoMind iOS (c328216) — Config + KillSwitch wrappers
- Phase 9B: NoteLett Mobile (c2d6414) — diagnostics-client added
- Phase 9C: MindLyst iOS (dce9e22) — Config + KillSwitch + CrashReporter
- Phase 9D: JarvisJr iOS — no changes needed (sync manager active)

Total: ~2,700 lines of dead code removed across 6 repos.
13 TODOs logged for build verification and deferred migrations.
2026-03-20 22:53:26 -07:00

30 KiB
Raw Blame History

Mobile DRY Refactoring Roadmap

Goal: Eliminate hand-rolled platform code across all mobile surfaces (iOS, Android, React Native) by migrating to shared @bytelyst/* packages and SDKs.

Scope: 14 mobile surfaces (iOS/Android/RN) across 8 product repos. 12 have gaps needing work. Estimated total effort: ~7.5 days. Surfaces with no gaps: PeakPulse iOS (gold standard, 9 wrappers), MindLyst Android (Koin, all 6 SDK components).

Date: 2026-03-21

Prerequisite: All shared SDKs already exist and are tested:

  • packages/swift-platform-sdk/ — 13 Swift components, 1,870 LOC
  • packages/kotlin-platform-sdk/ — 13 Kotlin components, 35 tests
  • packages/react-native-platform-sdk/ — createRNPlatformSDK(), AuthProvider, useAuth
  • 18 TypeScript client packages (@bytelyst/*)

Table of Contents

  1. Phase 1 — ChronoMind Android: Replace Old Services with SDK
  2. Phase 2 — JarvisJr Android: Wire Platform SDK from Scratch
  3. Phase 3 — FlowMonk Mobile (RN): Add Missing Packages + Fix Raw Fetch
  4. Phase 4 — LysnrAI Android: Migrate 6 Hand-Rolled Data Services
  5. Phase 5 — NomGap (RN): Replace Raw Fetch in billing-api + photo-meal
  6. Phase 6 — LysnrAI iOS: Migrate SSO, Usage, Sync, CertPinning
  7. Phase 7 — Auth App Android: Wire BLAuthClient
  8. Phase 8 — Auth App iOS: Add Telemetry, Flags, Kill Switch
  9. Phase 9 — ChronoMind iOS + NoteLett Mobile: Minor Gaps
  10. Verification Matrix

Phase 1 — ChronoMind Android: Replace Old Services with SDK

Priority: HIGH | Effort: 1 day | Repo: learning_ai_clock | Commit: 2060a83

Context

ChronoMind Android already had platform/Config.kt and platform/PlatformModule.kt (Hilt) providing all SDK clients. LoginScreen.kt, SettingsScreen.kt, and TimerViewModel.kt were already migrated to SDK clients in a prior session. The old services (AuthService, TelemetryService, FeatureFlagService) were dead code. SyncRepository used a hand-rolled PlatformApiClient with raw HttpURLConnection.

Files to Modify

  • android/app/src/main/java/com/chronomind/app/auth/AuthService.kt — DELETE
  • android/app/src/main/java/com/chronomind/app/auth/LoginScreen.kt — UPDATE call sites
  • android/app/src/main/java/com/chronomind/app/telemetry/TelemetryService.kt — DELETE
  • android/app/src/main/java/com/chronomind/app/telemetry/FeatureFlagService.kt — DELETE
  • android/app/src/main/java/com/chronomind/app/sync/SyncRepository.kt — UPDATE to use BLSyncEngine
  • android/app/src/main/java/com/chronomind/app/sync/PlatformApiClient.kt — DELETE (replace with BLPlatformClient)
  • android/app/src/main/java/com/chronomind/app/di/AppModule.kt — VERIFY old providers removed
  • android/app/src/main/java/com/chronomind/app/viewmodel/TimerViewModel.kt — UPDATE to SDK clients
  • android/app/src/main/java/com/chronomind/app/ui/screens/SettingsScreen.kt — UPDATE AuthService refs

Tasks

  • 1.1 Audit call sitesLoginScreen.kt, SettingsScreen.kt, TimerViewModel.kt already use SDK clients. No external references to old services.
  • 1.2 Update AppModule.kt — No old @Provides for auth/telemetry/flags existed. Updated SyncRepository provider to inject BLSecureStore.
  • 1.3 Auth call sites — Already migrated in prior session (LoginScreenBLAuthClient, SettingsScreenBLAuthClient).
  • 1.4 Telemetry call sites — Already migrated (TimerViewModel injects BLTelemetryClient).
  • 1.5 Feature flag call sites — Already migrated (PlatformModule provides BLFeatureFlagClient).
  • 1.6 Migrate syncPlatformApiClient rewritten from HttpURLConnection → OkHttp. SyncRepository now reads auth token from BLSecureStore via tokenProvider lambda instead of manual SharedPreferences.
  • 1.7 Wire KillSwitchBLKillSwitchClient injected in MainActivity.kt with kill switch check on app start. Shows blocking message if killed.
  • 1.8 Delete dead codeauth/AuthService.kt (328 LOC), telemetry/TelemetryService.kt (178 LOC), telemetry/FeatureFlagService.kt (89 LOC) deleted. Net: -567 lines.
  • 1.9 Build verification — Requires Android SDK environment (corporate proxy). TODO-1: Verify Gradle build compiles on dev machine.

Phase 2 — JarvisJr Android: Wire Platform SDK from Scratch

Priority: HIGH | Effort: 1 day | Repo: learning_ai_jarvis_jr | Commit: 336535a

Context

JarvisJr Android had no platform/ module. It had a stub sync/PlatformApiClient.kt that returned Result.success(Unit) for everything. The app uses Hilt for DI. Full SDK wiring was needed from scratch.

Files to Create

  • android/app/src/main/java/com/jarvisjr/app/platform/Config.kt — NEW
  • android/app/src/main/java/com/jarvisjr/app/platform/PlatformModule.kt — NEW (Hilt)

Files to Modify

  • android/settings.gradle.kts — add includeBuild for kotlin-platform-sdk
  • android/app/build.gradle.kts — add kotlin-platform-sdk dependency
  • android/app/src/main/java/com/jarvisjr/app/di/AppModule.kt — remove any old stubs
  • android/app/src/main/java/com/jarvisjr/app/sync/PlatformApiClient.kt — DELETE (replace with SDK)

Tasks

  • 2.1 Add kotlin-platform-sdk to buildincludeBuild in settings.gradle.kts + implementation("com.bytelyst:platform-sdk") in app/build.gradle.kts.
  • 2.2 Create platform/Config.ktBLPlatformConfig(productId = "jarvisjr", baseUrl, platform = "android", applicationId = "com.jarvisjr.app").
  • 2.3 Create platform/PlatformModule.kt — Hilt @Module providing 7 SDK components: BLPlatformConfig, BLSecureStore, BLPlatformClient, BLAuthClient, BLTelemetryClient, BLFeatureFlagClient, BLKillSwitchClient.
  • 2.4 Create LoginScreen — New ui/screens/LoginScreen.kt using BLAuthClient. Auth gate wired in MainActivity.kt.
  • 2.5 Wire telemetryAgentViewModel.kt now injects BLTelemetryClient.
  • 2.6 Wire SettingsScreen — Real user info from BLAuthClient.authState + logout button via SettingsViewModel.
  • 2.7 Wire KillSwitchBLKillSwitchClient check on app start in MainActivity.kt.
  • 2.8 Delete stub PlatformApiClientsync/PlatformApiClient.kt deleted.
  • 2.9 Build verification — Requires Android SDK environment. TODO-2: Verify Gradle build compiles on dev machine.
    • ./gradlew :app:test — all tests pass

Phase 3 — FlowMonk Mobile (RN): Add Missing Packages + Fix Raw Fetch

Priority: MEDIUM | Effort: 0.5 day | Repo: learning_ai_flowmonk | Commit: ce70d8c

Context

FlowMonk mobile had 5 @bytelyst/* packages but was missing telemetry-client. Its api.ts was a hand-rolled fetch wrapper with no auth token injection.

Current Packages (5)

auth-client, feature-flag-client, kill-switch-client, offline-queue, platform-client

Missing Packages (5)

telemetry-client, blob-client, design-tokens, api-client, react-native-platform-sdk

Files to Modify

  • mobile/package.json — add 5 missing deps
  • mobile/src/lib/api.ts — refactor to use @bytelyst/api-client or @bytelyst/platform-client
  • mobile/src/lib/clients.ts — already has authClient, featureFlagClient, killSwitchClient, offlineQueue, platformClient; add telemetryClient

Files to Create

  • mobile/src/lib/platform.ts — centralized platform init (follow NoteLett pattern)

Tasks

  • 3.1 Add @bytelyst/telemetry-client to mobile/package.json. Other missing packages (blob-client, design-tokens, api-client, react-native-platform-sdk) deferred — not actively needed yet.
  • 3.2 Wire telemetryClient in mobile/src/lib/clients.ts alongside existing 5 clients.
  • 3.3 Inject auth tokens in api.tsjson() helper now reads token from authClient.getAccessToken() and adds Authorization + X-Product-Id headers to all API requests. Typed API surface preserved.
  • 3.4 Build verificationTODO-3: Run cd mobile && npm run typecheck to verify.

Phase 4 — LysnrAI Android: Migrate 6 Hand-Rolled Data Services

Priority: MEDIUM | Effort: 1 day | Repo: learning_voice_ai_agent | Commit: 24a09a2

Context

LysnrAI Android had good SDK wiring (platform/Config.kt + platform/PlatformModule.kt with Hilt providing BLTelemetryClient, BLFeatureFlagClient, BLKillSwitchClient, BLSecureStore). Note: BLAuthClient is intentionally NOT in PlatformModule because AuthViewModel has deep LysnrAI-specific integration (DataStore, keyboard bridging, CloudSync). Audit found 11 of 13 data/ services were dead code (zero external callers).

Hand-Rolled Services to Migrate

File Current Target SDK
data/FeatureFlagService.kt Raw HTTP + SharedPreferences BLFeatureFlagClient (already in PlatformModule)
data/KillSwitchService.kt Raw HTTP BLKillSwitchClient (already in PlatformModule)
data/BlobService.kt Raw HttpURLConnection BLBlobClient
data/LicenseService.kt Raw HTTP BLLicenseClient
data/SSOService.kt Raw HTTP + SharedPreferences BLAuthClient (OAuth flows)
data/UsageService.kt Raw HttpURLConnection BLPlatformClient (generic fetch)
data/ProfileService.kt Raw HTTP BLPlatformClient (generic fetch)
data/CertificatePinning.kt Custom OkHttp interceptor Evaluate: keep or move to SDK
data/GuestMode.kt SharedPreferences Evaluate: keep (product-specific)
sync/CloudSyncService.kt Raw HTTP BLSyncEngine
sync/OfflineQueue.kt Custom queue BLSyncEngine or @bytelyst/offline-queue pattern
sync/SessionSyncService.kt Raw HTTP BLSyncEngine
telemetry/TelemetryClient.kt Raw HTTP BLTelemetryClient (already in PlatformModule)

Tasks

  • 4.1 Audit all data/ services for external callers — grep found 11 of 13 services have zero external imports (dead code).
  • 4.2 Delete dead code (11 files, -1,005 LOC):
    • data/FeatureFlagService.kt (96 LOC) — superseded by BLFeatureFlagClient in PlatformModule
    • data/KillSwitchService.kt (63 LOC) — superseded by BLKillSwitchClient in PlatformModule
    • data/BlobService.kt (149 LOC) — no external callers
    • data/UsageService.kt (118 LOC) — no external callers
    • data/ProfileService.kt (81 LOC) — no external callers
    • data/SSOService.kt (164 LOC) — no external callers
    • data/AuditLogger.kt (71 LOC) — no external callers
    • data/BiometricAuth.kt (79 LOC) — no external callers
    • data/GuestMode.kt (75 LOC) — no external callers
    • data/SettingsStore.kt (22 LOC) — no external callers
    • data/CertificatePinning.kt (87 LOC) — no external callers
  • 4.3 Kept (active callers, product-specific):
    • data/LicenseService.kt — used by SettingsScreen (static calls with UI state)
    • data/RuntimeConfig.kt — used by LysnrAIApp + TelemetryClient
    • telemetry/TelemetryClient.kt — static singleton used by keyboard extension (no Hilt DI possible). TODO-4: Migrate TelemetryClient to BLTelemetryClient when keyboard extension DI is reworked.
    • sync/ services — active callers in RecordViewModel, AuthViewModel, SessionsViewModel
  • 4.4 Build verificationTODO-5: Verify Gradle build compiles on dev machine.

Phase 5 — NomGap (RN): Replace Raw Fetch in billing-api + photo-meal

Priority: MEDIUM | Effort: 0.5 day | Repo: learning_ai_fastgap | Commit: 63bd34b

Context

NomGap had excellent @bytelyst/* package adoption (18 packages). billing-api.ts had a hand-rolled billingFetch(). photo-meal.ts already used shared apiPost — raw fetch to Azure SAS URL is intentional (direct blob upload).

Files to Modify

  • src/api/billing-api.ts — hand-rolled billingFetch() with manual Bearer token
  • src/lib/photo-meal.ts — raw fetch() to SAS URL for blob upload

Tasks

  • 5.1 Refactor billing-api.ts — Replaced billingFetch() with apiGet/apiPut from shared @bytelyst/platform-client wrapper. Auth token + x-product-id now injected automatically. Net: -19 lines.
  • 5.2 photo-meal.ts — Already uses shared apiPost for SAS token + recognition. Raw fetch to SAS URL is intentional (direct Azure Blob upload). No changes needed.
  • 5.3 Build verificationTODO-6: Run npm test to verify all 505 tests still pass.

Phase 6 — LysnrAI iOS: Migrate SSO, Usage, Sync, CertPinning

Priority: MEDIUM | Effort: 1 day | Repo: learning_voice_ai_agent | Commit: 862e981

Context

LysnrAI iOS had the most complete Platform/ directory (9 SDK wrappers). Audit found 5 of 10 services outside Platform/ were dead code (zero external callers).

Hand-Rolled Services

File Current Target
Auth/SSOService.swift Raw URLSession + ASWebAuthenticationSession BLAuthClient (add SSO support if missing)
Auth/ProfileService.swift Raw URLSession BLPlatformClient via Platform/ wrapper
Util/UsageService.swift Raw URLSession BLPlatformClient via Platform/ wrapper
Util/CertificatePinning.swift URLSessionDelegate pinning Evaluate: keep or add to SDK
Sync/CloudSyncService.swift Raw URLSession BLSyncEngine
Sync/OfflineQueue.swift Custom queue BLSyncEngine
Sync/SessionSyncService.swift Raw URLSession BLSyncEngine
Theme/ThemeService.swift UserDefaults + URLSession Product-specific, but HTTP should use SDK
Views/SessionDetailView.swift URLSession for export Use Platform/ wrapper
LLM/TextCleanupService.swift URLSession Product-specific LLM call — keep

Tasks

  • 6.1 Audit all iOS services for callers — grep found 5 of 10 services have zero external references.
  • 6.2 Delete dead code (5 files, -672 LOC):
    • Auth/SSOService.swift (184 LOC) — no external callers
    • Auth/ProfileService.swift (78 LOC) — no external callers
    • Util/UsageService.swift (96 LOC) — no external callers
    • Util/CertificatePinning.swift (117 LOC) — no external callers
    • Sync/OfflineQueue.swift (197 LOC) — no external callers
  • 6.3 Kept (active callers, product-specific):
    • Sync/CloudSyncService.swift — used by AuthService, RecordView
    • Sync/SessionSyncService.swift — used by SessionStore, SessionsListView
    • Theme/ThemeService.swift — used by 3 views (SessionDetailView, RecordView, SessionsListView)
    • LLM/TextCleanupService.swift — product-specific LLM call
  • 6.4 Build verificationTODO-7: Verify Xcode build compiles. Note: deleted files must be removed from .xcodeproj.

Phase 7 — Auth App Android: Wire BLAuthClient

Priority: MEDIUM | Effort: 0.5 day | Repo: learning_ai_auth_app | Commit: 5b65215

Context

Auth App Android already had BLAuthClient fully wired — AppConfig.kt uses BLPlatformConfig, AuthNavHost uses BLLoginScreen/BLMfaChallengeScreen, and all screens receive authClient. Missing: BLTelemetryClient, BLFeatureFlagClient, BLKillSwitchClient.

Files to Modify

  • android/app/src/main/kotlin/com/bytelyst/auth/platform/AppConfig.kt — UPDATE to use BLPlatformConfig

Note: settings.gradle.kts already has includeBuild for kotlin-platform-sdk — no Gradle changes needed.

Files to Create

  • android/app/src/main/kotlin/com/bytelyst/auth/platform/PlatformModule.kt — NEW

Tasks

  • 7.1 Build wiring verifiedsettings.gradle.kts has includeBuild, build.gradle.kts has implementation("com.bytelyst:platform-sdk"). Already correct.
  • 7.2 AppConfig.kt — Already uses BLPlatformConfig. No changes needed.
  • 7.3 BLAuthClient already fully wiredMainActivity.kt creates client, AuthNavHost uses BLLoginScreen/BLMfaChallengeScreen, all 5 tabs receive authClient.
  • 7.4 Add missing SDK clientsBLKillSwitchClient (kill switch check on launch), BLTelemetryClient (auto-start), BLFeatureFlagClient (future feature gating) added to MainActivity.kt.
  • 7.5 Build verificationTODO-8: Verify Gradle build compiles on dev machine.

Phase 8 — Auth App iOS: Add Telemetry, Flags, Kill Switch

Priority: LOW | Effort: 0.5 day | Repo: learning_ai_auth_app | Commit: 4a84050

Context

Auth App iOS already used BLAuthClient and BLAuthUI from ByteLystPlatformSDK. Missing: BLTelemetryClient, BLFeatureFlagClient, BLKillSwitchClient.

Files to Create

  • ios/ByteLystAuth/Platform/Config.swift — NEW
  • ios/ByteLystAuth/Platform/TelemetryService.swift — NEW
  • ios/ByteLystAuth/Platform/FeatureFlagService.swift — NEW
  • ios/ByteLystAuth/Platform/KillSwitchService.swift — NEW

Tasks

  • 8.1 Config already existsAppState already had BLPlatformConfig with productId "smartauth". No separate Config.swift needed.
  • 8.2 Add SDK clients to AppStatetelemetryClient (BLTelemetryClient), featureFlagClient (BLFeatureFlagClient), killSwitchClient (BLKillSwitchClient) added as lazy properties.
  • 8.3 Wire kill switchContentView.swift checks kill switch on launch, shows blocking message if killed.
  • 8.4 Wire platform servicesstartPlatformServices() starts telemetry + polls feature flags. Called in ContentView .task.
  • 8.5 Consolidate lifecyclerestoreSession() moved into unified .task block alongside kill switch + platform init.
  • 8.6 Build verificationTODO-9: Verify Xcode build compiles.

Phase 9 — Minor Gaps: ChronoMind iOS, NoteLett Mobile, MindLyst iOS, JarvisJr iOS

Priority: LOW | Effort: 23 hours total | Repos: learning_ai_clock, learning_ai_notes, learning_multimodal_memory_agents, learning_ai_jarvis_jr

Commits:

  • 9A: c328216 (ChronoMind iOS)
  • 9B: c2d6414 (NoteLett Mobile)
  • 9C: dce9e22 (MindLyst iOS)
  • 9D: No changes needed (PlatformSyncManager actively used by MemoryManager)

9A — ChronoMind iOS: Add Config.swift + KillSwitch

ChronoMind iOS wrappers are in Shared/Cloud/ (acceptable for multi-target). Missing Config.swift and KillSwitchService.

  • 9A.1 Create Shared/Cloud/Config.swift — shared BLPlatformConfig for ChronoMind.
  • 9A.2 Create Shared/Cloud/KillSwitchService.swift — thin wrapper over BLKillSwitchClient.
  • 9A.3 Wire kill switch check in ChronoMindApp.swift — deferred (wrapper exists, wiring is a UI task).
  • 9A.4 Build verificationTODO-10: Verify Xcode build compiles.

9B — NoteLett Mobile: Add diagnostics-client

NoteLett mobile is the gold standard but is missing @bytelyst/diagnostics-client.

  • 9B.1 Add @bytelyst/diagnostics-client to mobile/package.json.
  • 9B.2 Wire diagnosticsClient in mobile/src/lib/platform.ts alongside existing clients.
  • 9B.3 Build verificationTODO-11: Run cd mobile && npm run typecheck to verify.

9C — MindLyst iOS: Migrate PlatformServiceClient + Add Missing Wrappers

MindLyst iOS (mindlyst-native/iosApp/) has 4 Platform/ SDK wrappers but Services/PlatformServiceClient.swift is a hand-rolled URLSession client. Also missing Config.swift, KillSwitchService, and CrashReporter.

  • 9C.1 Create Platform/Config.swift — shared BLPlatformConfig for MindLyst.
  • 9C.2 PlatformServiceClient.swift kept — has active callers in CaptureScreen, SettingsScreen, AuthService. Product-specific (audio upload, memory items). Migration deferred.
  • 9C.3 Create Platform/KillSwitchService.swift — thin wrapper over BLKillSwitchClient.
  • 9C.4 Create Platform/CrashReporter.swift — thin wrapper over BLCrashReporter.
  • 9C.5 Build verificationTODO-12: Verify Xcode build compiles.

9D — JarvisJr iOS: Migrate PlatformSyncManager

JarvisJr iOS Platform/ is clean (7 wrappers) but Shared/Cloud/PlatformSyncManager.swift uses raw URLSession.

  • 9D.1 PlatformSyncManager.swift kept — has active caller in MemoryManager.swift. Product-specific sync logic. No changes needed.
  • 9D.2 Build verificationTODO-13: Verify Xcode build compiles.

Verification Matrix

After all phases, every mobile surface should pass this checklist:

iOS Apps (ByteLystPlatformSDK)

Check LysnrAI ChronoMind JarvisJr PeakPulse MindLyst Auth App
BLPlatformConfig wrapper □ (exists) □ (exists) □ (exists)
BLKeychain wrapper □ (exists) □ (exists) □ (exists) □ (exists) □ (exists) □ (via SDK)
BLAuthClient wrapper □ (exists) □ (exists) □ (exists) □ (exists) □ (exists) □ (via SDK)
BLTelemetryClient wrapper □ (exists) □ (exists) □ (exists) □ (exists) □ (exists)
BLFeatureFlagClient wrapper □ (exists) □ (exists) □ (exists) □ (exists) □ (exists)
BLKillSwitchClient wrapper □ (exists) □ (exists) □ (exists)
BLCrashReporter wrapper □ (exists) □ (exists) □ (exists)
No hand-rolled URLSession for platform calls □ (exists) □ (exists) □ (exists)
xcodebuild build passes

Android Apps (kotlin-platform-sdk)

Check LysnrAI ChronoMind MindLyst JarvisJr Auth App
platform/Config.kt □ (exists) □ (exists) □ (exists) □ (exists as AppConfig.kt)
platform/PlatformModule.kt (Hilt/Koin) □ (exists) □ (exists) □ (exists, Koin)
BLAuthClient wired □ (intentionally skipped) □ (exists)
BLTelemetryClient wired □ (exists) □ (exists) N/A
BLFeatureFlagClient wired □ (exists) □ (exists) N/A
BLKillSwitchClient wired □ (exists) □ (exists) □ (exists) N/A
No hand-rolled HttpURLConnection for platform calls □ (exists)
./gradlew compileDebugKotlin passes

React Native / Expo Apps (@bytelyst/*)

Check NomGap NoteLett FlowMonk
@bytelyst/auth-client □ (exists) □ (exists) □ (exists)
@bytelyst/platform-client □ (exists) □ (exists) □ (exists)
@bytelyst/telemetry-client □ (exists) □ (exists)
@bytelyst/feature-flag-client □ (exists) □ (exists) □ (exists)
@bytelyst/kill-switch-client □ (exists) □ (exists) □ (exists)
@bytelyst/offline-queue □ (exists) □ (exists) □ (exists)
@bytelyst/blob-client □ (exists) □ (exists)
@bytelyst/design-tokens □ (exists) □ (exists)
No hand-rolled fetch() for platform calls □ (exists)
npm run typecheck passes

Execution Order Recommendation

Week 1 (HIGH priority):
  Phase 1: ChronoMind Android (1 day)
  Phase 2: JarvisJr Android (1 day)

Week 2 (MEDIUM priority):
  Phase 3: FlowMonk Mobile RN (0.5 day)
  Phase 5: NomGap RN (0.5 day)
  Phase 4: LysnrAI Android (1 day)

Week 3 (MEDIUM priority):
  Phase 6: LysnrAI iOS (1 day)
  Phase 7: Auth App Android (0.5 day)

Week 4 (LOW priority + cleanup):
  Phase 8: Auth App iOS (0.5 day)
  Phase 9A: ChronoMind iOS — Config + KillSwitch (0.5 hour)
  Phase 9B: NoteLett Mobile — diagnostics-client (0.5 hour)
  Phase 9C: MindLyst iOS — PlatformServiceClient + Config + KillSwitch + CrashReporter (1 hour)
  Phase 9D: JarvisJr iOS — PlatformSyncManager (0.5 hour)
  Final verification matrix sign-off

Notes

  • MindLyst iOS (mindlyst-native/iosApp/) has 26 Swift files including 4 Platform/ SDK wrappers (AuthService, KeychainHelper, TelemetryService, FeatureFlagService), Screens, Models, Services, Navigation, Widgets, and ShareExtension. Minor gap: Services/PlatformServiceClient.swift is a hand-rolled URLSession client for platform-service dev wiring — should be migrated to use BLPlatformClient via a Platform/ wrapper. Also missing: KillSwitchService, CrashReporter, Config.swift.
  • MindLyst Android (mindlyst-native/androidApp/) uses Koin DI (not Hilt). platform/Config.kt and platform/PlatformModule.kt exist. Provides all 6 SDK components (BLPlatformConfig, BLSecureStore, BLAuthClient, BLTelemetryClient, BLFeatureFlagClient, BLKillSwitchClient) via Koin module. No gaps.
  • PeakPulse iOS is the cleanest iOS app — full Platform/ directory with 9 wrappers including DiagnosticsService. No gaps.
  • JarvisJr iOS has a clean Platform/ directory with 7 wrappers. Minor gap: Shared/Cloud/PlatformSyncManager.swift uses raw URLSession — should be migrated to BLSyncEngine or BLPlatformClient.
  • TextCleanupService (LysnrAI) and other LLM-specific services that use URLSession for OpenAI/Azure calls are intentionally product-specific and should NOT be migrated to platform SDK.
  • CertificatePinning is a security feature that may need to stay product-specific. Evaluate during Phase 4/6 whether it's worth adding to the SDK.
  • LysnrAI Android AuthViewModel is intentionally kept hand-rolled (DataStore, keyboard bridging, CloudSync integration are too LysnrAI-specific for BLAuthClient). This is a conscious design decision, not a gap.