store-listing

Physical-device dogfood gate

The pre-store gate from APP_STORE_DEPLOYMENT.md, turned into something you can actually work through on a phone and paste into issue #1684 with the boxes ticked.

Run it on a physical device, on a dev or preview build, against productioneas.json's preview/production profiles already carry the prod Supabase URL and EXPO_PUBLIC_API_URL. A simulator will not surface the things this gate exists to catch: real network flakiness, safe-area chrome, permission dialogs, keyboard behaviour, deep links.

Record device + OS + build profile at the top when you post results:

Device: iPhone 15 Pro / iOS 26.x    Build: preview (EAS)    Backend: prod

Status of this gate

Not run. It needs a physical device; nothing in this task could execute it. Everything below is the checklist, plus — under "Known suspects" — a list of things static analysis says will fail, so whoever runs it knows where to look first.


1. Auth

  • Sign up with a new email; the confirmation path works end to end
  • Sign in with an existing account
  • Turnstile challenge (if a site key is in the build) renders, completes, and doesn't block the button forever
  • Wrong password shows a readable error, not a raw Supabase string
  • Session survives a force-quit and relaunch
  • Stale/revoked token signs you out cleanly rather than hanging (#1655)
  • Sign out returns to the auth stack with no flash of authed UI

2. Entries — the core loop

  • Create an entry: title, body, mood, 2+ tags, assigned notebook
  • Create an entry without a mood — saves, and the server-inferred mood appears
  • Read it back in the detail view; formatting survives
  • Edit it — every field persists after a reload
  • Delete it, with a confirmation step
  • Long entry (2,000+ words) scrolls and saves without lag
  • Entry with emoji, non-Latin characters and line breaks round-trips intact
  • Pull-to-refresh on the list picks up an entry created on the web

3. Notebooks

  • Create, rename and delete a notebook
  • Entry counts are right after adding and removing entries
  • Notebook detail lists the correct entries
  • Creating an entry from inside a notebook pins it there

4. Goals

  • Create a goal, edit it, delete it
  • Record a check-in; progress updates
  • Goal detail matches what the web dashboard shows for the same goal

5. Sleep

  • Log a night; it appears on the Stream
  • Editing the same date updates rather than duplicating (one entry per night)
  • Hours validation rejects nonsense (negative, 30+)
  • Search matches on title and body
  • Clearing the query restores the full list
  • No-match state reads "No entries found", not a blank screen
  • Search behaves with 100+ entries loaded (it filters the loaded list client-side — note if that's visibly wrong on a large journal)
  • Share an entry from the app; the link opens on the web
  • Tapping a hivejournal.com/share/... link from another app opens it in HiveJournal, not Safari/Chrome (iOS applinks:, Android intent filter)
  • Cold-start deep link works (app fully quit, then tap the link)
  • A revoked/expired share link fails gracefully

8. Stream, Analysis, and the rest of the tabs

  • Stream mixes entries, sleep and drops in the right order
  • Journal Analysis loads and renders a readable reflection
  • JQ chat (floating button) opens, sends, and receives
  • DreamPro list and detail load
  • JQ Bridge invitations and connections load
  • Drops received list loads and mark-as-read sticks
  • Graphene tab plays audio; playback pill docks above the tab bar and survives navigation (#1644)

9. Settings and account

  • Edit profile — display name and profile photo (exercises the photo-library permission prompt)
  • Email preferences save
  • Export Data — see "Known suspects"
  • Delete Account is reachable, warns clearly, and actually deletes (use a throwaway account — this is irreversible)

10. Chrome, layout and theme

  • Safe-area insets correct on a notched/Dynamic Island device — nothing under the status bar or home indicator (#1644)
  • Landscape is either locked out or doesn't break layout (orientation: portrait in app.json)
  • Keyboard doesn't cover the entry editor's save control
  • Floating overlays (satisfaction slider, action button, JQ) don't sit on top of the tab bar
  • Dark mode — device set to dark: the app is light-only and consistent, native modals/keyboard/alerts included (see "Known suspects")
  • Text still fits at the largest OS text size

11. Network and error states

  • Airplane mode: every screen shows an error, not a spinner forever
  • Slow 3G (Network Link Conditioner / emulator throttle): no duplicate submits, no torn UI
  • Losing connectivity mid-save surfaces a real failure message
  • Recovering connectivity refetches without a restart
  • Backgrounding for 10+ minutes and returning refreshes rather than showing stale data

12. Empty states

Sign in as a brand-new account and check each reads intentionally, not broken:

  • Entries list · [ ] Notebooks · [ ] Goals · [ ] Sleep · [ ] Stream
  • Analysis · [ ] Dreams · [ ] Drops · [ ] JQ Bridge

13. Performance

  • Cold start under ~3s to first usable screen
  • Scrolling a 100+ entry list stays smooth
  • No visible jank switching tabs
  • Memory stays flat over ~10 minutes of use

Known suspects — check these first

Found by static analysis while preparing the store artifacts. Each is expected to fail; confirm on device and file (or link) an issue for whatever reproduces.

#WhereWhat's expected to happenEvidence
1Settings → Export DataFixed in #1706 — it used to throw before writing anything (expo-file-system@19 moved documentDirectory / writeAsStringAsync / EncodingType off the default export). Ported to the File/Paths API. Still needs the device check: the share sheet on iOS and Android, and the clipboard fallback when Sharing.isAvailableAsync() is false — neither was verifiable without hardware.SettingsScreen.tsx
2Dark modeFixed in #1707 — there still isn't any dark mode (no screen reads the color scheme; 71 hardcoded backgroundColor: '#fff'), but app.json no longer claims one: userInterfaceStyle went "automatic""light", and expo-system-ui was added so that declaration is honored on Android too (without it the setting is a no-op there and only warns at prebuild). Still needs the device check on a build cut after this change: on a phone set to dark, native modals, the keyboard, alerts and action sheets should all come up light.app.json, App.tsx:24
3DreamPro → dream detail → AI breakdownLikely a crash or a dead button: the screen imports generateAIBreakdown, saveAIBreakdown and AIDreamBreakdown from services/api, none of which are exported.DreamDetailScreen.tsx:23-27
4Action panel step promptsSame shape — imports getStepPrompts, which services/api doesn't export.ActionPanel.tsx:13
5Permission prompts (location, camera, photos)Fixed in #1709 — no longer a suspect, but still worth eyeballing on device: each prompt should read as purpose-specific with the right app name, the app should never ask for "Always" location, and no microphone prompt should appear anywhere.app.json plugins
6Duplicate style keysStyleSheet.create objects with the same key twice — the second silently wins, so some styling never applies. Cosmetic, but visible.DreamDetailScreen.tsx:816, WorkoutWindowCheckInScreen.tsx:517
7Reporting / blockingThere is no way to report or block anyone, anywhere in the product, even though Drops and JQ Bridge deliver other people's content. Both stores require one.product-wide

How to post results

Paste the whole checklist into issue #1684 with boxes ticked, the device line at the top, and for each failure either a new issue link or a one-line "expected, tracked in #N". A gate with unexplained blanks isn't a gate.

Dogfood Gate — Docs | HiveJournal