Install expo-updates and the eoas CLI, and configure the client against https://ota.apps.jbrunton.co.uk. app.json stays the static source of truth for version, buildNumber, and versionCode, which EAS rewrites during a release build. A new app.config.js spreads it and layers on the updates block, because XPREM selects a release channel from a build-time request header and that value differs per EAS build profile. - updates.url points at the XPREM manifest endpoint, /manifest - runtimeVersion uses the appVersion policy, so the runtime version is the store-visible expo.version and a native change requires a store build - expo-channel-name comes from RELEASE_CHANNEL, set per EAS build profile: development, staging (preview profile), and production - expo-app-id and an empty xprem-branch header are declared at build time, since expo-updates only sends headers that existed when the build was made - code signing uses keyid main and rsa-v1_5-sha256 against a certificate at certs/certificate.pem, skipped when DISABLE_CODE_SIGNING is set so a dev client can run against the packager The XPREM app id and the code-signing certificate are still placeholders pending the update server deployment. The config throws a descriptive error whenever RELEASE_CHANNEL is set while either is unresolved, so a misconfigured build fails at config resolution rather than shipping a client that can never validate a manifest. The native projects are Expo CNG output and are left untouched: the expo-updates config plugin embeds the real app id and certificate contents, so they are regenerated as a reviewed source change once both values land. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sauci
Sauci is a couples connection product built as a full-stack npm/Turborepo workspace.
Applications
| Path | Surface |
|---|---|
apps/mobile |
Expo React Native customer app |
apps/admin |
Vite/React administration app |
apps/web |
Next.js marketing and redemption app |
apps/supabase |
database, auth, realtime, storage, and Edge Functions |
apps/mcp |
authenticated internal MCP service |
packages/shared |
shared TypeScript contracts |
Bootstrap and run
Use Node 20.10.0 from .nvmrc, Docker-compatible containers, and tmux.
npm ci
scripts/dev-local.sh reset
scripts/dev-local.sh up
The launcher starts local Supabase, Edge Functions, web, admin, MCP, and Expo in one tmux session. See local stack documentation for ports, logs, native launch commands, and troubleshooting.
Verify
npm run verify:fast # lint, typecheck, unit/contract tests
npm run verify:full # fast checks, builds, Supabase integration
npm run verify:e2e # running-stack Playwright journeys
npm run verify # complete pre-PR gate
Native black-box flows use npm run test:mobile:e2e. Pull requests run static
and full-stack gates and retain browser traces/screenshots/videos on failure.
Agent harness
Start with AGENTS.md and the documentation index.
Task/risk agent routing lives in docs/agents/routing.md,
repository skills live under .codex/skills, and verified lessons follow the
learning promotion lifecycle.
Database schema changes must use committed files in apps/supabase/migrations.
Remote migration tools and DDL through MCP SQL execution are forbidden.