Mobile App
The Orazaka app for iOS and Android as it runs today, on the iOS simulator and the Android emulator against the local stack: sign-in, Studios, streamed chat, jobs — how to run it, its tests, and which screens do not read the server yet.
The app is krizaka/orazaka-mobile-client: Expo SDK 53, React
Native 0.79, React Navigation, cloned in the workspace at orazaka-apps/ui/orazaka-mobile-client. It talks to the
edge (:8088) with Authorization: Bearer — the same services, the same interceptor pipeline and the same
entitlements as the web client.
What this page describes was run on 2026-10-12 on the iOS 27 simulator (iPhone 17, Xcode 27) and the Android 16
emulator (Pixel 8 image) against the local Orazaka stack, signed in as the demo persona (Eric, orazaka demo seed). Where a screen shows something that does not
come from the server, it says so.
| Platform | State |
|---|---|
| iOS simulator (iOS 27) | ✅ builds and runs against the local stack — sign-in, Studios, chat, jobs, connectors, profile |
| Android emulator (Android 16) | ✅ development build runs against the local stack — sign-in, Studios, jobs, profile |
| iPhone / store builds | ❌ no EAS project, no signing — the app runs from a development build only |
| Expo SDK | ⚠️ 53 — the move to SDK 57 (the other Krizaka apps) is planned; two stopgaps below keep 53 building and launching on Xcode 27 / iOS 27 |
1. What the app does today
Sign in
E-mail and password (POST /api/v1/auth/login); create an account (/api/v1/auth/register, which may ask to verify
the e-mail first), forgot and reset password. The session (token, username, authorities) is kept in the device's
secure storage only (expo-secure-store); the navigator shows the app stack only while a session exists.

Studios
The Studio catalogue (GET /api/v1/studios) — locked Studios listed, not hidden, exactly as on the web — then a
Studio's page (GET /api/v1/studios/<key>: price per run, install) and its run screen (the Studio's input form, the
run started and polled: /api/v1/studios/installations/<id>/runs, /api/v1/studios/runs/<id>). The run screen shows
each step's status while it works, then the outputs. Today the outputs are the model's text as it comes: Markdown is
not rendered (**Nom:** shows as is) and a step's metadata (provider, durationMs) is printed with its content.

Chat
A message is streamed back token by token (Server-Sent Events, /api/v1/chat/stream/<conversation>), through the
interceptor pipeline and the model routing of the stack it runs on. Below, Eric's question and the answer of the local
stack. Before the first message the screen shows a presentation card of the sovereign chat — an illustration, not a
conversation.

Jobs
The account's jobs (GET /api/v1/jobs): jobs per day and by kind (charts from @krizaka/charts), then each job with
its status and its age.

Connectors and profile
Connecteurs lists the account's connector credentials (GET /api/v1/credentials; none for Eric).
Profil reads GET /api/v1/profile (name, e-mail, roles) and leads to Abonnement, Console d'intentions
(POST /api/v1/intent/route) and Gouvernance, then sign-out.

What does not come from the server yet
- Système (the "System Entropy" tab) draws fixed values written in the app — it is not a measure of the stack.
- Gouvernance lists sample interceptor policies written in the app.
- Abonnement shows plan cards written in the app; subscribing happens on the web.

On Android (development build, Android 16 emulator):

A short recording of the smoke run (sign in → a Studio → jobs → profile → sign out): ios-smoke.mp4.
2. Run it on a simulator
Requirements: macOS with Xcode 27 and an iOS simulator runtime, CocoaPods, Node 22, JDK 21 for the stack, and the
workspace cloned (node scripts/workspace.mjs clone, then npm install in orazaka-apps/ui).
# 1. The stack: infrastructure, then the services the app calls
orazaka start --mode dev
orazaka dev --only edge,identity,studio,job,billing,router
orazaka demo seed # the demo persona (local only)
# 2. The app
cd orazaka-apps/ui/orazaka-mobile-client
npx expo run:ios # prebuild, pods, build, install, MetroThe iOS simulator shares the Mac's network, so the default edge address (http://localhost:8088) works. On a phone or
the Android emulator, set EXPO_PUBLIC_EDGE_URL (http://10.0.2.2:8088 for the emulator, then
npx expo run:android; a development build allows plain HTTP).
Two stopgaps keep SDK 53 working with today's tools, both to delete with the move to SDK 57:
- Xcode 27 / iOS 27 —
plugins/with-xcode27.js:fmt(React Native 0.79) compiled in C++17, no pod below iOS 15.1, and the scene life cycle iOS 27 requires (an app built with the iOS 27 SDK that does not adoptUISceneis stopped at launch). - React — React Native renders with its own copy of React's renderer, which must match React exactly: 0.79 ships
19.0.0 while the web apps of the workspace run 19.2.x. The workspace installs React 19.0.0 for this package only
(
overridesinorazaka-apps/ui/package.json) andmetro.config.jsresolves everyreactimport to it.
3. Tests
| What | Where | |
|---|---|---|
| Unit | the SSE parser, the API client, the session store, job statistics, Studio input schemas | src/**/__tests__/*.test.ts (Jest project logic) |
| Render | the app on edge responses recorded as the demo persona: sign-in and its refusal, a stored session, the Studios, the jobs, the profile and sign-out, an unreachable edge | src/__tests__/app.test.tsx (Jest project screens), fixtures in src/__fixtures__/api |
| Smoke | Maestro: sign in → a Studio → jobs → profile → sign out, on a simulator | .maestro/smoke.yaml |
The repository's CI builds the workspace and runs npm run validate (lint, type-check, both Jest projects) on every
pull request. The Maestro flow runs on a Mac with a simulator and the stack up:
maestro test .maestro/smoke.yaml -e [email protected] -e ORAZAKA_PASSWORD=<password>4. What is missing
- Expo SDK 57 — and with it the end of the two stopgaps above.
- Android: a run on a phone.
- Builds for a phone: an EAS project, signing, TestFlight / an APK.
- Words: the screens mix English and French written in the code; the app has no message catalogue yet.
- Système, Gouvernance, Abonnement: read from the server instead of values written in the app.
- Theme: dark only; the tab bar has no icons yet.