product

Mobile JQ Presence — the OS layer under the Living Voice

Status: strategy / not built. Authored 2026-07-08. This is the native-mobile companion to AR_GLASSES_LIVING_VOICE.md: where that doc is the glasses hardware layer under the Living Voice, this is the phone layer — how much of "JQ is with me, talks to me, and I can talk back without opening the app" iOS and Android actually permit. Like the AR doc, it is not a pull-forward from Workstream A (writing) or Odessa, and it inherits the Living Voice ethics/cost wall verbatim.

Where the mobile app is today: Expo 54 / RN 0.81 (apps/mobile), pre-release. expo-av (audio playback) is in; no push notifications, no on-device speech, no Siri/App-Intents wiring exist yet. So this is greenfield — a ceiling map, not a refactor.


Thesis in one line

You cannot build "an app that always listens and talks whenever it wants" — both OSes forbid it. What you can build is a set of OS-sanctioned hooks that compose into ambient presence, and the payload they all want — a short, cached, render-once voice clip — is exactly what the shipped Living Voice layer (sayInUserVoice, the nudge cadence engine, the audio-first player + MediaSession) already produces.

The two hard walls (both platforms)

  1. No always-on custom wake word. No background mic listening for "Hey JQ." iOS forbids it for third parties; Android technically allows it via a foreground service + persistent notification, but at heavy battery cost and real Play Store policy risk. Don't.
  2. No unprompted speech from a backgrounded app. JQ can't start talking on its own. Every proactive moment needs a sanctioned trigger: a notification, a scheduled local notification, a push, or a system-assistant invocation.

Everything below lives inside these walls.


A. JQ reaching / speaking to you (proactive)

HookCan JQ "speak"?Notes
Push notification (APNs/FCM)iOS: yes, ~30s — a pre-rendered voice clip plays as the notification sound on the lock screen, app not running. Android: yes, more — a high-priority FCM push can start a foreground service and play full TTS/audioThe single most important channel. iOS caps the spoken part at a 30s custom sound (bundled or downloaded via a notification-service extension); Android is far more permissive
Local scheduled notificationSame as above, server-freeThe existing occasion-aware cadence (morning intention / next-step / at-risk streak) schedules these locally — fires even offline
Live Activity / Dynamic Island (iOS) / ongoing notification (Android)No voice, but presentA persistent "today's intention" surface, server-updatable via push
Lock-screen / home widgetTap-to-hearPassive presence: today's nudge visible, one tap plays the cached clip
CarPlay / Android AutoYes — audio-firstThe context where "JQ speaks a nudge" is most natural; the shipped audio-first player + MediaSession maps straight onto the car now-playing surface

Ceiling for "JQ talks to us anytime": short server-pushed spoken nudges (30s clip on iOS, richer on Android) + persistent visual presence. Not long unprompted conversations from the background.

B. You talking to JQ without opening the app

The sanctioned answer: borrow the system assistant as your microphone.

HookStrengthWhat it gives
Siri + App Intents / App Shortcuts (iOS 16+)Strong"Hey Siri, ask JQ for my next step" → your intent runs and Siri speaks JQ's reply without visibly opening the app. Custom phrases auto-register. The real "voice interaction, app not running"
iPhone Action Button / Control CenterStrongOne press → a JQ shortcut → speak. No "Hey Siri" needed
Shortcuts automations (iOS)Medium"When I get home / connect CarPlay → ask JQ for a reflection." Context-triggered voice
Google Assistant / App Actions (Android)Weaker / in fluxGoogle scaled back custom App Actions; the robust path is App Shortcuts surfaced to Assistant — more limited than iOS App Intents. Verify current state at build time

Ceiling for "voice-in without opening the app": genuinely good on iOS (App Intents), noticeably weaker on Android right now. You ride the platform assistant; you don't get your own wake word.


Top integrations, ranked (feasibility × reuse of the shipped voice layer)

  1. Voice-clip-as-notification-sound — JQ's cached nudge plays on the lock screen. Reuses sayInUserVoice verbatim. iOS 30s cap; Android unbounded. The wedge.
  2. Siri App Intent: "ask JQ" — spoken Q→A without opening the app (iOS). Highest-impact, iOS-only.
  3. Local scheduled nudges — the existing cadence engine, emitted as OS notifications. Offline, free.
  4. CarPlay / Android Auto audio companion — nudges + journal playback in the car; rides the audio-first player.
  5. Action Button / lock-screen tap-to-talk — instant capture or "talk to JQ."
  6. Live Activity "today's intention" — persistent ambient presence, push-updated.
  7. Home/lock-screen widget — glanceable nudge, tap to hear.
  8. Android foreground-service TTS — the one place JQ can speak a longer proactive line (Android's permissiveness).
  9. Shortcuts automations — location/time/NFC-triggered JQ reflections (iOS).
  10. Voice journaling via intent — "Hey Siri, tell JQ…" logs an entry in your voice, app closed.

iOS vs Android asymmetry

  • iOS: weaker proactive (30s notification-sound cap), stronger voice-in (App Intents are excellent).
  • Android: stronger proactive (foreground-service TTS, richer notifications), weaker voice-in (App Actions scaled back).

Design for both: the notification-sound nudge (#1) works everywhere; the Siri intent (#2) is the iOS standout; Android's edge is #8 (longer proactive speech).

What it costs in Expo terms

  • Already have: expo-av — playback is done.
  • Easy adds (config plugins, no ejection): expo-notifications (rich push + local + custom iOS sound), expo-speech (on-device TTS fallback).
  • Needs a native module + dev build (not Expo Go): Siri App Intents / SiriKit, CarPlay / Android Auto, Live Activities. These are the high-value ones and the real engineering lift — a custom Expo config plugin wrapping native intent definitions.

Ethics & cost inheritance (non-negotiable)

Inherits the Living Voice load-bearing wall, unchanged:

  • Consent v2 scope + the JQ Bridge permission graph for whose voice may speak.
  • Read-only vs. generative bright line for any enduring/deceased voice.
  • Cost guardrails: cache rendered clips (a notification sound is rendered once, reused forever), keep nudges short, rate-limit, never force re-render, reuse tts-spend.ts.
  • Calm, not noisy — the mobile version of this rule is the sharpest: a phone that pings is the opposite of the brand. Proactive nudges must be rare, user-tunable, off by default, and honor OS Focus/Do-Not-Disturb (never request Critical/Time-Sensitive interruption levels for a nudge). The whole point is presence, not notification spam.

The wedge / recommendation

Build #1 + #2 + #3: voice-clip notifications (both platforms) + the Siri "ask JQ" intent (iOS) + local scheduled nudges. All three reuse the shipped voice layer, and together they deliver ~80% of the felt "JQ is with me" experience within the OS rules — no wake-word fantasy. Android voice-in (App Actions) and CarPlay are second-wave.

Sequencing

  1. expo-notifications + the voice-clip-as-sound path (#1) — the shared surface, both platforms.
  2. Local scheduled nudges (#3) onto the existing cadence engine.
  3. iOS Siri App Intent "ask JQ" (#2) — the first native-module lift (dev build + config plugin).
  4. CarPlay / Live Activities / Android foreground-service TTS — second wave, per the asymmetry above.

See also

MOBILE JQ PRESENCE — Docs | HiveJournal