Instrument iOS cold-start phases

Merged
AS
4mo ago
+765-16

Summary

  • trace Expo OTA, JavaScript bootstrap, auth restore, splash dismissal, and deferred service bootstrap in one sampled mobile startup transaction
  • mark perceived app load after splash dismissal and emit correlated startup phase logs
  • document signed Release measurements and retain the current launch policy because the reported delay did not reproduce

Evidence

The signed ad-hoc Release bundle passed strict code-signature verification and rendered the login screen without a fatal runtime error. Three force-stop launches reached interactive in 712.7 ms, 968.0 ms, and 659.6 ms; a clean reinstall took 863.8 ms. OTA was 631.6–942.0 ms and all measured JS/auth/splash phases were at most 11 ms. No evidence supports changing fallbackToCacheTimeout.

Production classification remains blocked by expired Axiom connector access and the absence of historical Sentry startup spans; the issue and incident baseline record this gap.

Validation

  • pnpm exec vitest run --project mobile packages/mobile/lib/telemetry.test.ts packages/mobile/app/_layout.cleanup.test.tsx packages/mobile/lib/auth-context.test.ts packages/mobile/lib/startup-telemetry.test.ts (37 passed)
  • mobile lint
  • mobile TypeScript
  • root lint
  • root, server, and web TypeScript
  • signed Release Simulator build/install/launch with four controlled startup traces
  • full unit/mobile run emitted all discovered files green, then was terminated after an unrelated scripts/compose-env.test.ts Docker CLI child hung during teardown under shared Docker contention

Fixes #2193

Summary by Sourcery

Instrument iOS mobile cold-start with correlated Sentry startup spans and logs across OTA, JavaScript, authentication, splash dismissal, and deferred service bootstrap, and document the measurements and incident outcome.

New Features:

  • Add a Mobile Startup trace coordinator that attributes iOS cold-start time across OTA launch, JavaScript readiness, authentication restore, splash hide, and deferred service bootstrap.
  • Emit structured app-startup logs mirroring startup phase durations and outcomes for Release audits and OTLP correlation.
  • Mark app interactivity after splash dismissal via Sentry.appLoaded() so native app-start spans reflect the first interactive screen.

Enhancements:

  • Sample only App Start and Mobile Startup traces in Sentry to control startup tracing volume.
  • Wire auth bootstrap, splash dismissal, and background service initialization to startup phase telemetry without changing user-facing behavior.
  • Track service bootstrap success and failures as a distinct startup phase that can be skipped when no authenticated session exists.

Documentation:

  • Document the iOS Release startup tracing behavior, evidence, and unchanged Expo updates policy in the mobile README.
  • Record the iOS cold-start incident, measurements, root cause status, fix, and remaining risk in the production incident baseline.
  • Add a TDD plan document describing the iOS cold-start spans implementation and validation strategy.

Tests:

  • Add unit tests for the startup telemetry coordinator covering OTA attribution, phase lifecycle, interactive marking, and error handling.
  • Extend auth-context, root layout, and telemetry tests to assert correct startup phase wiring and Sentry sampling behavior.

Summary by cubic

Instrumented iOS cold start to attribute time across OTA, JavaScript, authentication, splash dismissal, and deferred service bootstrap, and to mark the app interactive at splash hide; no launch policy change was needed. Fixes #2193.

  • New Features
    • Added packages/mobile/lib/startup-telemetry.ts to start a "Mobile Startup" transaction via @sentry/react-native with child spans for each phase.
    • Captures expo-updates metadata (including Updates.launchDuration) and creates an "OTA launch" span that ends at JavaScript start.
    • Wired AuthProvider and _layout.tsx to start/finish phase spans, call Sentry.appLoaded() after splash, record outcomes (ready/authenticated/unauthenticated/deferred/error), start a new auth span after a deferred restore, and measure deferred service bootstrap.
    • Emits structured app-startup logs mirroring phase durations for Release audits and OTLP correlation.
    • Samples only "App Start" and "Mobile Startup" via tracesSampler in lib/telemetry.ts.
    • Added focused tests (startup-telemetry.test.ts) and updated docs (README.md, incident baseline); kept fallbackToCacheTimeout unchanged.