Skip to content

Upgrade Expo to SDK 57 and React Native 0.86#300

Merged
FleetAdmiralJakob merged 8 commits into
mainfrom
codex/expo-sdk-57
Jul 20, 2026
Merged

Upgrade Expo to SDK 57 and React Native 0.86#300
FleetAdmiralJakob merged 8 commits into
mainfrom
codex/expo-sdk-57

Conversation

@FleetAdmiralJakob

@FleetAdmiralJakob FleetAdmiralJakob commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

Upgrades Dayova from Expo SDK 56 to stable Expo SDK 57 and aligns the React Native, Expo, and native-support dependency set.

  • Expo ~56.0.12~57.0.7
  • React Native 0.85.30.86.0
  • Expo Router, Dev Client, Updates, Notifications, UI, and the installed Expo modules aligned to SDK 57
  • Reanimated ^4.5.0, Worklets 0.10.0, Gesture Handler ^2.32.0, and Keyboard Controller 1.21.9
  • Clerk Expo ^3.7.8
  • Expo Status Bar config plugin registered explicitly
  • pnpm lockfile regenerated with the SDK 57 dependency graph
  • Native iOS system-appearance bridge added so root/status-bar theming follows live system changes
  • Module README added for the native contract, lifecycle, operations, risks, validation, troubleshooting, and removal criteria
  • Mobile-app ADR added for the bridge rationale, decision history, alternatives, and consequences
  • Latest main OTA-safety and portable Expo-script changes reconciled; unused-code analysis now supplies APP_VARIANT portably

This PR also fixes pre-existing unused theme exports, includes two narrowly scoped Android compatibility patches, and carries the iOS appearance fixes found during native validation.

Changelog and compatibility review

Reviewed:

The generated iOS project and checked-in Android project build against the SDK 57 / React Native 0.86 native stack.

iOS deployment target and appearance compatibility

Expo SDK 57 supports iOS 16.4+. Dayova-owned native code preserves that baseline:

  • DayovaSystemAppearance.podspec declares iOS 16.4.
  • iOS 17+ uses registerForTraitChanges.
  • iOS 16.4–16.x uses traitCollectionDidChange.
  • Source-shape tests pin the podspec floor and verify the expected ordering of the modern and legacy observer markers; they do not compile Swift or prove UIKit callback behavior.
  • Debug and optimized Release both compiled the module for arm64-apple-ios16.4-simulator.

The generated Dayova app target remains iOS 17.0 because the native Clerk Expo SDK/config plugin requires and writes iOS 17.0. That requirement already existed on the PR merge base; the Expo SDK 57 upgrade and appearance module did not introduce it. It is documented in docs/contexts/platform/CONTEXT.md for later re-evaluation.

Android compatibility fixes

React Native Gradle plugin on Windows

React Native 0.86's Gradle settings plugin applies the Foojay toolchain resolver. Gradle 9.3.1 can miscompile that settings script on Windows before plugin resolution, consistent with gradle/gradle#36323.

patches/@react-native__gradle-plugin@0.86.0.patch removes only the unnecessary Foojay settings block. Dayova already requires JDK 17. Autolinking, codegen, and the application plugin are unchanged.

Keyboard controller with Fabric modals

On React Native 0.86, opening Dayova's React Native modal on Android produced:

Fabric View [-1] does not have SurfaceId associated with it

patches/react-native-keyboard-controller@1.21.9.patch carries the Fabric surface ID from the modal's topShow event into the focused-input observer. The ordinary non-modal path retains the package's existing lookup. Both patches are documented in patches/README.md with verification and removal criteria.

Theme cleanup and maintenance

Knip-reported theme implementation details are now private, and the obsolete light-only NAV_THEME alias is removed while NAV_THEMES remains.

Dark-theme tokens are mirrored between CSS and src/lib/theme-variables.ts because CSS and native consumers need different representations. src/lib/theme-css.test.ts detects drift; color changes must update both.

Validation

Final validated head: 8a52c3d (review fixes plus latest-main reconciliation after native validation).

Repository and Expo checks

  • pnpm install --frozen-lockfile with pnpm 10.25.0
  • pnpm check
  • pnpm format:check
  • pnpm test — 32 files / 143 tests
  • pnpm check:unused
  • npx --yes expo-doctor@latest — 20 checks
  • pnpm exec expo install --check
  • git diff --check
  • iOS production bundle — 7,786 modules; 25 logical assets / 24 copied asset files
  • Android production bundle — 7,797 modules
  • Local EAS Update resources — 7,786 modules, Hermes bytecode, 25 assets, asset map, and metadata; nothing published
  • Production OTA guard — correctly blocked publication because the native fingerprints differ from distributed 1.0.3 binaries and the Android baseline is unverified

Native iOS

Environment:

  • macOS 26.5.2 (25F84)
  • Xcode 26.6 (17F113)
  • iPhone 17 simulator (iPhone18,3) on iOS 26.5

Results:

  • Clean Debug simulator build passed with an .xcresult.
  • Simulator-signed Debug (Sign to Run Locally) passed and launched.
  • Production-style no-signing Release passed with embedded bundle and Xcode product validation.
  • Simulator-signed Release passed and cold-launched without Metro.
  • Live system light → dark → light passed in Debug and Release.
  • Background/foreground resume retained the same Dayova PID.
  • The appearance module compiled at the iOS 16.4 target in Debug and Release.

The complete iOS walkthrough covered:

  • Cold launch and authenticated-session restoration
  • Home data
  • Learning plans and plan details
  • Repeated create-type modal open/close
  • New-exam entry
  • Profile input and keyboard behavior
  • Settings, notifications, and learning-time screens
  • Light/dark/system appearance
  • Background/foreground resume
  • Safe areas, navigation gestures, sheets/modals, and keyboard avoidance

The final iOS-floor patch changes only the appearance observer. On exact head 73834a8, Debug and Release were rebuilt, launched, and re-smoked for cold launch, live appearance/status-bar repaint, and resume. The retained simulator no longer had an authenticated Clerk session, so the broader authenticated walkthrough remains the immediately preceding native-validation run on 687970c; no auth or feature-flow code changed afterward.

No data was edited or submitted. No physical iPhone was connected.

Native Android

Validated on Windows/JDK 17/Gradle 9.3.1 and a Pixel 9 on Android 16:

  • Clean SDK 57 Debug and patched APK builds passed.
  • Exact-head APK installed and hash-verified.
  • Local Release passed with an embedded 7,797-module bundle.
  • Release cold launch without Metro passed.
  • Home, plans/details, learning cards, create/new-exam entry, profile keyboard, resume, and appearance transitions passed.
  • No final Worklets mismatch, Fabric failure, missing route/module, fatal exception, or JavaScript error.
  • The exact-head development APK was restored afterward.

Log findings and limitations

Signed Debug/Release logs contained no native crash, JavaScript exception, Fabric/New Architecture failure, missing native module, layout/safe-area failure, keychain entitlement failure, or runtime-version mismatch.

Observed diagnostics:

  • Third-party deprecation and script-phase warnings only; no appearance-module warning or compile error.
  • UIKit emits an existing future-facing UIScene lifecycle warning on iOS 26.5.
  • The local CNG project has no EAS channel header, so its background Expo Updates request returns HTTP 400 and the embedded bundle is used. Production EAS builds define channel: production in eas.json; local update-resource generation passed with runtime 1.0.3.
  • Unsigned simulator builds emit expected Keychain/SecureStore -34018 diagnostics. Simulator-signed builds eliminate them.
  • Physical iPhone and minimum-OS runtime testing were unavailable. The Dayova module was compiled at iOS 16.4; the app remains at Clerk's pre-existing iOS 17.0 minimum.

Maintenance note

Re-evaluate both pnpm patches when React Native, Gradle, or Keyboard Controller changes. Re-evaluate the app-wide iOS 17.0 minimum when Clerk lowers its native requirement or is replaced. Keep mirrored CSS/native theme tokens synchronized; the drift test enforces this.

Summary by CodeRabbit

  • Improvements
    • Updated iOS system appearance handling to stay in sync with system light/dark changes automatically.
    • Refreshed dark-mode theming variables and applied them consistently across the app.
    • Improved keyboard focus and layout behavior, including within modal screens.
    • Refined auth-flow step animations for smoother transitions.
    • Improved status bar presentation for consistency.
  • Bug Fixes
    • Prevented validation analytics from running until user data is available.
  • Documentation
    • Expanded patch documentation and updated the Expo UI bottom-sheet guidance link.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@FleetAdmiralJakob, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 11 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 36e081d7-5063-4c3f-9200-a00299dacbf5

📥 Commits

Reviewing files that changed from the base of the PR and between 73834a8 and 8a52c3d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • CONTEXT-MAP.md
  • app.config.ts
  • docs/contexts/mobile-app/CONTEXT.md
  • docs/contexts/mobile-app/adr/0001-use-local-ios-system-appearance-bridge.md
  • docs/contexts/platform/CONTEXT.md
  • modules/dayova-system-appearance/README.md
  • package.json
  • src/lib/ios-appearance-module.test.ts
  • tests/package-scripts.test.ts
📝 Walkthrough

Walkthrough

Expo SDK and React Native dependencies were upgraded, with Gradle and keyboard-controller patches registered and documented. A native iOS system-appearance module and theme wiring were added, alongside analytics guards and authentication-flow animation updates.

Changes

Expo and React Native upgrade

Layer / File(s) Summary
Expo and React Native dependency upgrade
app.config.ts, package.json, pnpm-workspace.yaml, docs/bottom-sheets.md
Expo SDK, React Native, supporting libraries, Babel preset, status-bar configuration, workspace settings, and versioned documentation were updated.
Gradle plugin patch
patches/@react-native__gradle-plugin@0.86.0.patch, patches/README.md
The Foojay Gradle settings plugin block was removed and patch verification instructions were added.
Keyboard surface ID patch
patches/react-native-keyboard-controller@1.21.9.patch, pnpm-workspace.yaml, patches/README.md
Keyboard observers now receive explicit surface IDs, with the patch registered and documented.

System appearance and theme wiring

Layer / File(s) Summary
Native appearance module
modules/dayova-system-appearance/*
A typed Expo module reports the iOS color scheme and emits appearance changes.
Theme resolution and dark variables
src/lib/system-color-scheme*, src/lib/theme.ts, src/lib/theme-variables.ts, src/app/_layout.tsx
System theme hooks, preference synchronization, dark CSS variables, and root NativeWind styling were added or updated.
Theme wiring validation
src/lib/theme-css.test.ts, src/lib/ios-appearance-module.test.ts
Tests verify dark variables, automatic appearance configuration, system-theme wiring, and iOS appearance implementation constraints.

Analytics and onboarding behavior

Layer / File(s) Summary
Convex analytics data guards
src/lib/analytics.ts, src/components/analytics-identity.tsx
Validation and next-day analytics wait for available Convex user data.
Authentication flow animations
src/features/auth/dayova-auth-flow.tsx
Question, chip, and goal option animations use updated entering or layout transitions.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ThemeProvider
  participant SystemColorHook
  participant DayovaSystemAppearance
  participant UIKitObserver
  ThemeProvider->>SystemColorHook: request system color scheme
  SystemColorHook->>DayovaSystemAppearance: getColorScheme and subscribe
  DayovaSystemAppearance->>UIKitObserver: observe trait changes
  UIKitObserver->>DayovaSystemAppearance: emit color scheme change
  DayovaSystemAppearance->>SystemColorHook: deliver onChange event
  SystemColorHook->>ThemeProvider: update resolved theme
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main dependency upgrade to Expo SDK 57 and React Native 0.86.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/expo-sdk-57

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@FleetAdmiralJakob

Copy link
Copy Markdown
Collaborator Author

Native iOS validation complete

Validated commit 86364a1 on:

  • macOS 26.5.2 (25F84)
  • Xcode 26.6 (17F113), the installed stable Xcode
  • iPhone 17 simulator (DAY-166 Evidence iPhone 17) on iOS 26.5
  • No unlocked physical iPhone was connected, so no device signing or Apple account configuration was changed.

Native build results

  • Debug iPhone simulator build: passed
  • Production-variant Release build for arm64 iPhone simulator: passed, installed, and launched from its embedded bundle
  • Generic iPhoneOS Release build with CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO: passed
  • Clean CNG regeneration/prebuild and CocoaPods install: passed; the existing Expo config and entitlements were preserved
  • The two pnpm patches remain unchanged and Android-only

Application exercise

Exercised the existing development account/data through cold launch and authenticated-session restoration, home data, learning plans, plan details and session content, repeated create-modal open/close, the full new-exam flow, profile text input with the software keyboard, settings, notifications and notification-time sheets, learning-time screens/editor, light/dark/system appearance, live OS appearance changes, background/foreground resume, safe areas, navigation/back gestures, sheets/modals, and keyboard avoidance.

A development-only exam and learning plan were created to validate the full flow. No production data was accessed or mutated.

Log findings

Final Debug and Release log passes contained no native crash/exception, React Native or JavaScript error, Fabric/New Architecture failure, missing native module, or safe-area/layout warning. Background/foreground restoration retained the active plan-detail screen.

A manually built local production Release reports an Expo Updates HTTP 400 because plain xcodebuild does not inject expo-channel-name. The committed production EAS profile still declares channel: production; its update URL and runtime version are present, and Expo Updates resource generation succeeds. No production update was published.

Fixes made during iOS validation

  • Enabled automatic native interface style and added a small iOS Expo module that reports the active key-window appearance. React Native 0.86's Appearance value was stale on this simulator during cold launch and live system changes.
  • Applied dark NativeWind variables through the React tree so mounted Fabric views update reliably when appearance changes.
  • Removed conflicting/redundant onboarding layout animations that caused first-transition chip content to render blank temporarily and emitted Reanimated/Fabric warnings.
  • Sequenced validation analytics mutations behind the Convex user query to avoid the authenticated-signup race observed in development logs.
  • Updated the Expo UI bottom-sheet documentation link to SDK 57 and added regression coverage for theme wiring/variables.

Final validation suite

  • pnpm install --frozen-lockfile with pnpm 10.25.0 under Node 22.23.1: passed
  • pnpm check: passed
  • pnpm test: 29 files / 128 tests passed
  • pnpm check:unused: passed
  • pnpm format:check: passed
  • npx --yes expo-doctor@latest: 20/20 passed
  • pnpm exec expo install --check: dependencies up to date
  • Production iOS export: passed (7,786 modules, 25 assets)
  • EAS Update iOS resource generation: passed (app.manifest generated)
  • git diff --check: passed

The Expo SDK 57 changelog, SDK 56→57 upgrade helper, and React Native 0.86 release notes were reviewed. The PR is non-draft and is ready for CI/CodeRabbit revalidation.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/lib/system-color-scheme.ios.ts (1)

5-20: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer useSyncExternalStore over useState + useEffect for external subscriptions.

Since React 18, useSyncExternalStore is the recommended hook for subscribing to external state (like a native module). It prevents "tearing" (where the UI might render an old value if the system appearance changes before the useEffect fires) and simplifies the code.

♻️ Proposed refactor using `useSyncExternalStore`
-import { useEffect, useState } from "react";
+import { useSyncExternalStore } from "react";
 import type { ResolvedTheme } from "~/lib/theme-preference";
 import DayovaSystemAppearance from "../../modules/dayova-system-appearance";
 
+const subscribe = (callback: () => void) => {
+	const subscription = DayovaSystemAppearance.addListener("onChange", callback);
+	return () => subscription.remove();
+};
+
+const getSnapshot = () => DayovaSystemAppearance.getColorScheme();
+
 export function useSystemColorScheme(): ResolvedTheme {
-	const [colorScheme, setColorScheme] = useState<ResolvedTheme>(() =>
-		DayovaSystemAppearance.getColorScheme(),
-	);
-
-	useEffect(() => {
-		const subscription = DayovaSystemAppearance.addListener(
-			"onChange",
-			(event) => setColorScheme(event.colorScheme),
-		);
-
-		return () => subscription.remove();
-	}, []);
-
-	return colorScheme;
+	return useSyncExternalStore(subscribe, getSnapshot);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/system-color-scheme.ios.ts` around lines 5 - 20, Update
useSystemColorScheme to use React’s useSyncExternalStore instead of useState and
useEffect for the DayovaSystemAppearance subscription. Provide a subscribe
callback that registers the existing onChange listener and returns its removal
cleanup, and provide a snapshot callback that reads
DayovaSystemAppearance.getColorScheme().
src/lib/theme-css.test.ts (1)

20-20: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use a more robust regex for extracting the CSS block.

The current regex \n\t\} depends strictly on the specific whitespace and indentation of the file. If global.css is reformatted (e.g., using spaces instead of tabs, or different line endings), the test will fail.

Using [^}]+ to match everything up to the first closing brace is more resilient to formatting changes.

♻️ Proposed refactor
-		const darkRoot = css.match(/\.dark:root\s*\{([\s\S]*?)\n\t\}/)?.[1];
+		const darkRoot = css.match(/\.dark:root\s*\{([^}]+)\}/)?.[1];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/theme-css.test.ts` at line 20, Update the darkRoot extraction regex
in the theme CSS test to terminate at the first closing brace using a
formatting-independent pattern such as [^}]+, instead of requiring a specific
newline and tab sequence. Preserve the existing .dark:root block matching and
captured-content behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/analytics.ts`:
- Around line 17-21: Update the analytics authentication flow to obtain
isConvexAuthenticated from useConvexAuth() rather than destructuring it from
useAuth(). Add the required convex/react import, and keep the existing user &&
isConvexAuthenticated guard for the api.users.getMe query so analytics activity
can execute when Convex authentication is valid.

---

Nitpick comments:
In `@src/lib/system-color-scheme.ios.ts`:
- Around line 5-20: Update useSystemColorScheme to use React’s
useSyncExternalStore instead of useState and useEffect for the
DayovaSystemAppearance subscription. Provide a subscribe callback that registers
the existing onChange listener and returns its removal cleanup, and provide a
snapshot callback that reads DayovaSystemAppearance.getColorScheme().

In `@src/lib/theme-css.test.ts`:
- Line 20: Update the darkRoot extraction regex in the theme CSS test to
terminate at the first closing brace using a formatting-independent pattern such
as [^}]+, instead of requiring a specific newline and tab sequence. Preserve the
existing .dark:root block matching and captured-content behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d71a9963-88ed-4cd6-8ee0-256fd1c22adb

📥 Commits

Reviewing files that changed from the base of the PR and between 38eec73 and 86364a1.

📒 Files selected for processing (18)
  • app.config.ts
  • docs/bottom-sheets.md
  • modules/dayova-system-appearance/LICENSE
  • modules/dayova-system-appearance/expo-module.config.json
  • modules/dayova-system-appearance/index.ts
  • modules/dayova-system-appearance/ios/DayovaSystemAppearance.podspec
  • modules/dayova-system-appearance/ios/DayovaSystemAppearanceModule.swift
  • modules/dayova-system-appearance/src/DayovaSystemAppearance.types.ts
  • modules/dayova-system-appearance/src/DayovaSystemAppearanceModule.ts
  • src/app/_layout.tsx
  • src/components/analytics-identity.tsx
  • src/features/auth/dayova-auth-flow.tsx
  • src/lib/analytics.ts
  • src/lib/system-color-scheme.ios.ts
  • src/lib/system-color-scheme.ts
  • src/lib/theme-css.test.ts
  • src/lib/theme-variables.ts
  • src/lib/theme.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • app.config.ts

Comment thread src/lib/analytics.ts Outdated
@FleetAdmiralJakob

Copy link
Copy Markdown
Collaborator Author

Native iOS validation complete (final pass)

Validated commit 687970c on:

  • macOS 26.5.2 (25F84)
  • Xcode 26.6 (17F113), stable /Applications/Xcode.app
  • iPhone 17 simulator, iOS 26.5 (751A0B09-3B1B-46AA-B900-F8B620D69331)
  • No unlocked physical iPhone was connected; signing/provisioning/Apple account settings were not changed.

Native results

  • Debug simulator build: passed and launched.
  • Debug cold launch: authenticated session restored directly to Home.
  • System appearance: live light → dark → light transitions passed without restart.
  • In-app appearance: Light, Dark, and System selections passed, including native chrome and app surfaces.
  • Production-variant Release simulator build: passed, embedded a 7,786-module Hermes bundle, installed as de.dayova.app, and launched without Metro.
  • Generic arm64 iPhone Release build: passed with CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO.
  • Standalone iOS production export: passed (7,786 modules, 25 assets).
  • EAS Update resource generation: passed (app.manifest).

App exercise

Exercised cold launch/session restoration, Home data, learning plans and plan details, learning session/quiz content, repeated create-modal open/close, new-exam flow, profile input and keyboard behavior, learning-time editor, notification settings and notification-time sheet, Light/Dark/System appearance, background/foreground resume, navigation gestures, sheets/modals, safe areas, and keyboard avoidance. Test-only records were created only in the development environment; production data was not mutated.

Log review

No native crashes/exceptions, JavaScript errors in the final clean Debug run, missing native modules, Fabric/New Architecture failures, safe-area/layout warnings, or runtime-version incompatibilities were found. Xcode 26.6 emits non-fatal upstream dependency warnings (React Native/Expo/Reanimated/Screens/SVG/keyboard-controller). The manual Release launch reports the expected Expo Updates HTTP 400 for a missing expo-channel-name, because a plain local xcodebuild does not inject the EAS profile channel; eas.json configures the production channel, and runtime-version plus EAS resource generation validated successfully.

A transient navigation-context error and localhost connection refusals in earlier diagnostic logs came from hot-loading a partially compiled Metro stylesheet and deliberately stopping/restarting Metro while diagnosing the appearance issue; neither recurred after the clean full bundle.

Fixes added during iOS validation

  • Kept the native iOS window appearance and React Native Appearance state synchronized on iOS 26.
  • Applied/cleared NativeWind theme variables deterministically and retained a native flex root during stylesheet initialization.
  • Replaced the initialization-sensitive NativeWind color-scheme setter with React Native 0.86's Appearance.setColorScheme API.
  • Addressed CodeRabbit's analytics auth guard by reading Convex auth state directly from useConvexAuth.
  • Hardened the theme CSS synchronization assertion.
  • Android-only pnpm patches were preserved unchanged.

Final suite

  • pnpm install --frozen-lockfile — passed with pnpm 10.25.0 / Node 22.23.1
  • pnpm check — passed
  • pnpm test — 29 files / 128 tests passed
  • pnpm check:unused — passed
  • pnpm format:check — passed
  • npx --yes expo-doctor@latest — 20/20 passed
  • pnpm exec expo install --check — dependencies up to date
  • git diff --check — passed

Remaining limitation: no physical iPhone was available, so device execution and signed archive installation were not performed. The unsigned arm64 device Release build passed. No TestFlight/App Store submission was made.

@Gamius00

Gamius00 commented Jul 19, 2026

Copy link
Copy Markdown
Member

@FleetAdmiralJakob I am to tired to review the PR yet, but Ill try to review tomorrow, because I want to read all changes without time pressure. Will add it to my todo with High Priority!

@linear-code

linear-code Bot commented Jul 20, 2026

Copy link
Copy Markdown

DAY-246

@FleetAdmiralJakob

Copy link
Copy Markdown
Collaborator Author

Native iOS follow-up completed on 73834a8.

The reported appearance-module floor is fixed: DayovaSystemAppearance now declares iOS 16.4, gates registerForTraitChanges behind iOS 17 availability, and uses traitCollectionDidChange on iOS 16.4–16.x. Debug and optimized Release both compiled the module for arm64-apple-ios16.4-simulator. Two regression tests guard the podspec floor and fallback.

One important attribution correction: the generated Dayova application target is still iOS 17.0 because @clerk/expo writes that target. The same Clerk requirement is present on the PR merge base, so the Expo 57 upgrade and new Dayova module did not raise the app-wide floor. This is now documented for later re-evaluation.

Validation environment:

  • macOS 26.5.2 (25F84)
  • Xcode 26.6 (17F113)
  • iPhone 17 simulator (iPhone18,3), iOS 26.5
  • No connected physical iPhone

Results:

  • Clean Debug and simulator-signed Debug builds passed.
  • Production-style no-signing Release and simulator-signed Release builds passed.
  • Signed Release cold-launched its embedded 7,786-module bundle without Metro.
  • Live light → dark → light and root/status-bar repaint passed in Debug and optimized Release.
  • Background/foreground resume retained the same process.
  • Repository suite passed: 30 files / 130 tests, pnpm check, formatting, Knip, Expo Doctor 20/20, Expo dependency check, frozen install, and git diff --check.
  • iOS production export passed: 7,786 modules, 25 logical assets.
  • Local EAS Update resources passed: Hermes bytecode, 25 assets, asset map, and metadata; nothing was published.

Signed-run logs have no native crash, JS exception, Fabric/New Architecture failure, missing module, safe-area/layout failure, keychain error, or runtime-version mismatch. Remaining disclosed diagnostics are the existing future UIScene warning and a local-CNG Expo Updates 400 because no EAS channel header is injected locally; the embedded bundle loads, eas.json defines the production channel, and resource generation passed. Unsigned-only -34018 keychain errors disappeared in simulator-signed builds.

The PR body is updated with the current native module, 130-test count, deployment-target rationale, full validation results, theme-token maintenance note, and remaining limitations.

@Gamius00

Gamius00 commented Jul 20, 2026

Copy link
Copy Markdown
Member

Please change target branch to 1.0.4, because we cant send it OTA. Directly merge is not possible. Because this blocks the other OTA updates.
Please create a new release branch for the App Launch

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/contexts/mobile-app/CONTEXT.md`:
- Around line 17-21: Update the documentation links in the mobile-app context
document to use relative paths from docs/contexts/mobile-app/ that correctly
reach the modules directory and the mobile-app ADR file, preserving the existing
link targets and descriptions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8c052cb1-9c25-474b-90a4-ec9fd9e216da

📥 Commits

Reviewing files that changed from the base of the PR and between 73834a8 and 5a23c04.

📒 Files selected for processing (6)
  • CONTEXT-MAP.md
  • docs/contexts/mobile-app/CONTEXT.md
  • docs/contexts/mobile-app/adr/0001-use-local-ios-system-appearance-bridge.md
  • docs/contexts/platform/CONTEXT.md
  • modules/dayova-system-appearance/README.md
  • src/lib/ios-appearance-module.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/contexts/platform/CONTEXT.md
  • src/lib/ios-appearance-module.test.ts

Comment thread docs/contexts/mobile-app/CONTEXT.md Outdated
@FleetAdmiralJakob
FleetAdmiralJakob merged commit d82619a into main Jul 20, 2026
6 checks passed
FleetAdmiralJakob added a commit that referenced this pull request Jul 20, 2026
Integrate PRs #300 and #305 while preserving the DAY-109 auth, routing, accessibility, local test, and Metro reliability work. Port the Windows Metro limiter to Expo 57 and align the native/Jest integration with React Native 0.86 and Node 24.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants