Skip to content

feat(ios): add native routing shell [roadmap:WF-ROADMAP-0016]#118

Merged
tcballard merged 2 commits into
mainfrom
codex/ios-native-shell-smoke
Jul 24, 2026
Merged

feat(ios): add native routing shell [roadmap:WF-ROADMAP-0016]#118
tcballard merged 2 commits into
mainfrom
codex/ios-native-shell-smoke

Conversation

@tcballard

@tcballard tcballard commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the opening native-shell slice of WF-ROADMAP-0016 Phase 2.

Adds:

  • a universal iOS 18+ Wayfinder app target for iPhone and iPad;
  • an adaptive SwiftUI shell with Chat, Threads, Destinations, and Settings;
  • a deterministic routing-preview flow backed by the generated Rust bridge;
  • compiled unit coverage for simple, structured, privacy-filtered, empty, and tab-contract states;
  • an iOS app build-and-test gate in Apple Mobile CI.

Scope

Included

  • Root @Observable application state and one navigation stack per tab.
  • Adaptive NavigationSplitView presentation for regular-width Chat.
  • Direct in-process calls to WayfinderRoutingBridge.
  • Honest preview destinations and route receipts that state no provider was contacted.
  • A checked-in Xcode project plus its XcodeGen source specification.
  • iOS Simulator and arm64 physical-device compile checks.

Excluded

  • Live provider execution, credentials, OAuth, or Keychain.
  • Conversation persistence, retention, migration, export, or deletion.
  • Apple Foundation Models execution.
  • Mac pairing or any localhost gateway dependency.
  • A Swift reimplementation of routing.

Product / Architecture Decisions

  • The app embeds the authoritative Rust routing core; it does not start or call a gateway.
  • Preview destinations exist only to prove typed eligibility and route planning. The UI labels them as non-executing candidates.
  • Privacy posture is supplied to the Rust plan call, so an on-device-only request cannot select the hosted preview.
  • iPhone uses tab-rooted navigation. Regular-width iPad Chat adapts to a split view without cloning the macOS window hierarchy.
  • The app target remains universal and deployment-gated at iOS/iPadOS 18.
  • Generated Swift and XCFramework products remain ignored and reproducible through the existing bridge script.

User-Facing Contract

Native UI

  • Chat accepts a message and previews its deterministic route.
  • The result identifies the candidate, execution boundary, routing tier, and score.
  • The result explicitly says that no provider was contacted and no message left the device.
  • Settings exposes the maximum execution boundary and reports that no Mac is required.

Runtime

  • Routing occurs in-process through WayfinderRoutingBridge.
  • No network request, credential read, provider call, persistence write, or localhost connection occurs.

Data and Exit Codes

  • This slice stores no conversation data or secrets.
  • CLI and process exit-code contracts are unchanged.

Verification

Ran

  • apple/scripts/build_routing_xcframework.sh
  • swift build --build-tests --package-path ios/WayfinderIOS --scratch-path /private/tmp/wayfinder-ios-swift-build-tests --triple arm64-apple-ios18.0-simulator --sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
  • swift build --package-path ios/WayfinderIOS --scratch-path /private/tmp/wayfinder-ios-device-build --triple arm64-apple-ios18.0 --sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk
  • swift format lint --recursive ios/WayfinderIOS/WayfinderIOS ios/WayfinderIOS/WayfinderIOSTests ios/WayfinderIOS/Package.swift
  • actionlint .github/workflows/apple-mobile-ci.yml
  • xcodebuild -list -project ios/WayfinderIOS/WayfinderIOS.xcodeproj
  • git diff --check
  • Apple Mobile CI run 30092322219: iPhone 17 Simulator,
    5 AppModelTests with 0 failures, and TEST SUCCEEDED.

Covered

  • The app module and test bundle compile against the arm64 iOS Simulator SDK.
  • The app module and embedded Rust library compile for an arm64 iOS device.
  • A simple prompt selects the on-device preview candidate.
  • A structured prompt selects the hosted preview when hosted execution is allowed.
  • On-Device Only excludes the hosted recommendation rather than silently crossing the boundary.
  • Empty input does not plan a route.
  • The four root tabs remain explicit and stable.

Local simulator execution is not claimed: this Mac has an iOS 26.5 SDK but only iOS 26.3-or-older Simulator runtimes, so Xcode reports every installed simulator as ineligible. Apple Mobile CI completed the actual xcodebuild test run on its matched runtime.

Review Path

  1. ios/WayfinderIOS/WayfinderIOS/AppModel.swift for bridge use, privacy, and route state.
  2. ios/WayfinderIOS/WayfinderIOS/ChatTabView.swift and RootView.swift for adaptive navigation and truthful UI.
  3. ios/WayfinderIOS/WayfinderIOSTests/AppModelTests.swift for the routing contract.
  4. ios/WayfinderIOS/project.yml, generated Xcode project, and Package.swift compile-check harness.
  5. Apple Mobile CI and the roadmap implementation note.

Notes For Reviewer

  • The empty Threads screen is intentional; persistence is the next isolated Phase 2 boundary.
  • Provider-looking rows are explicitly labelled as routing candidates only.
  • App icon artwork is intentionally not introduced in this architecture slice.
  • Physical-device runtime execution still remains before the Phase 1 exit gate can be called complete.

Implementation Process

Implemented with AI assistance under the accepted roadmap and ADR contracts; final scope, review, and acceptance decisions remain with the maintainer.

@tcballard
tcballard marked this pull request as ready for review July 24, 2026 12:29
@tcballard
tcballard merged commit 565edd0 into main Jul 24, 2026
4 checks passed
@tcballard
tcballard deleted the codex/ios-native-shell-smoke branch July 24, 2026 12:29
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.

1 participant