Context. surface mobile · domain shell-routing · route / · auth anon (shell renders for guest; deep launches may gate per-domain) · source apps/oshun/mobile/app/(tabs)/index.tsx
Last walked. not yet walked
Purpose#
Home is the mobile shell's anchor tab: it greets by daypart, leads with the
single strongest "return" thread, and offers companion bridges, capture/share
intake, calendar sync, Iris hand-off, an Assistant entry, direct domain
launches, recommendations, Tara favorites, the mocap studio entry, and a
quick-actions tray. It is the (tabs)/index screen rendered inside the tab
navigator (OSHUN header, no stack header).
Entry points#
- Shell nav: the Home tab (
shell-tab-home, accessibilityLabel "Home"). - App cold start (deep-link hydration may land here via
useDeepLinkHydration). - Return navigation from any pushed domain/mocap/v2/v3 screen.
- Notification routing bridge can route here.
Layout regions#
- Header: tab-navigator header titled
OSHUN(dark#1f1a14); no back. - Hero / above-the-fold:
home-daypart-hero— kicker "Daily rhythm", greeting + date, daypart title/body, "Current arc" card (with lead-continuity preview), primary + secondary action, meta chips, and a 3-card daypart rail. - Main (vertical
ScrollView): sections — Tara quick starts, Return first (continuity), Iris hand-off, Companion bridges, Calendar sync, Capture intake, Share ingest, Active companion, Veritas briefing, Assistant entry, Direct launches (domain switcher + domain rail), Offline continuity, Daily footing, Recommendation carousel, Tara favorites, Capture studio (flagged), Quick actions entry (flagged). - Footer / sticky bottom: tab bar;
QuickActionsTraybottom sheet (flagged).
States#
- Loading —
<350msshell bootstrap gated in_layout; screen returns empty<View testID="mobile-home-screen">untilcurrentPrimaryStepresolves. No skeleton on Home itself. - Empty — no continuity threads → "No live return journeys" empty card; no favorites → "No favorites yet" empty card.
- Populated (short) — continuity cards prioritized by current daypart; one lead feature card + supporting lane.
- Populated (long) — long
ScrollView; horizontal favorites strip and recommendation carousel scroll independently. - Error (recoverable) — N/A: Home data is in-module fixtures, no fetch.
- Error (unrecoverable) — caught by
OshunErrorBoundaryshell-wide. - Offline —
GlobalOfflineBanner(shell) +ShellOfflineContinuityCardsection render; pull-to-refresh still simulates a 900ms refresh. - Permissions-denied (camera/mic/photos) —
MobileCaptureIntakeCardshows per-permissionprompt/deniedstate;handleStartCapturere-asks viagrantMobileCapturePermissionand warns when blocked. - Gated — Home renders for guests;
domainSwitcher,quickActionsTray,mocapCaptureStudioflags hide their sections when false. - iOS vs Android — safe-area via tab bar height; tab bar 84pt iOS / 72pt
Android (
(tabs)/_layout). No screen-level inset handling on Home.
Interactions#
- Pull-to-refresh (RefreshControl)
- Function:
handleRefresh— haptic, 900ms delay, resetslastRefreshedAt. - Gesture/touch: pull down at top of scroll.
- Telemetry:
triggerMobileFlowHaptic('home-refresh-start'/'-complete').
- Function:
- Daypart primary action (
home-daypart-primary-action, Pressable)- Function:
launchJourney(currentJourney)→router.push(step.action.href). - Gesture/touch: tap; label =
currentJourney.primaryAction.label.
- Function:
- Review continuity (
home-daypart-secondary-action, Pressable)- Function:
handleContinue→ push to Activity tab.
- Function:
- Daypart rail card (
home-daypart-card-<id>, Pressable ×3)- Function:
launchJourney(journey)→ push that journey's primary step href.
- Function:
- Tara ritual hero (
DomainEntryHero, primary + secondary entries)- Function:
launchHomeTaraRitual(entry)— sets current domain to tara,trackTaraCardTap, haptic,router.push(entry.href). - testID:
home-tara-ritual-entry-<ritualId>.
- Function:
- E2E launch morning opening (button, only when E2E hooks enabled)
- accessibilityLabel "Launch morning opening"; hint announced; testID
home-tara-e2e-launch-morning-opening.
- accessibilityLabel "Launch morning opening"; hint announced; testID
- Lead continuity card (
ContinuityCardfeature, "Resume now")- Function: card's
onPress→ set current domain, telemetry, haptic,buildDomainRouteHref(domain, {originTab:'home', params:{path,ref}}).
- Function: card's
- Supporting continuity row (
home-continuity-card-<id>, Pressable)- Function: same
onPress; accessibilityRole button; accessibilityLabel joins eyebrow/title/summary/meta. Shows progress track when present.
- Function: same
- Iris hand-off card (
MobileIrisHandoffCard)- Resume →
handleResumeIrisHandoff(push resolved route); Send back →handleSendIrisHandoffBack(push Assistant with hand-off token prompt).
- Resume →
- Companion bridge row (
home-companion-bridge-<id>, Pressable)- Function:
launchJourneyStep(step)→ set domain (if domain step), push href.
- Function:
- Calendar sync card (
MobileCalendarSyncCard)- Sync now → Activity tab w/
filter=calendar-sync; Open item → domain route; Review inbound → Assistant w/ change-count prompt.
- Sync now → Activity tab w/
- Capture intake card (
MobileCaptureIntakeCard)- Request permission →
grantMobileCapturePermission; Start capture → domain/assistant route when ready, else re-prompt/warn; Review redaction → Assistant route w/ redaction prompt.
- Request permission →
- Share ingest card (
MobileShareIngestCard)- Open target → Library tab w/
share=openparams.
- Open target → Library tab w/
- Active companion card (
MobileActiveCompanionCard)- Control press →
handleActiveCompanionControl; open/next_step push domain route; complete/skip only fire haptics.
- Control press →
- Veritas briefing section (
VeritasBriefingHomeSection)- Featured/Claim → veritas domain route; Action → ask-assistant or veritas
route per
action.kind.
- Featured/Claim → veritas domain route; Action → ask-assistant or veritas
route per
- Assistant entry (
AssistantEntryCard,mobile-home-assistant-entry)- Function: opens Assistant with
homeAssistantPrompt.
- Function: opens Assistant with
- Domain switcher entry (
DomainSwitcherEntry, flagged on)- Change/Action →
openDomain(value).
- Change/Action →
- Domain launch row (
home-domain-launch-<id>, Pressable ×N)- Function:
openDomain(card.id); shows "Current focus"/"Planned preview" tag.
- Function:
- Recommendation carousel (
RecommendationCarousel)- Item tap →
launchRecommendation(per-domain card build + deep route); feedback hide/less/more → haptic only.
- Item tap →
- Favorite card (Pressable, horizontal strip)
- Function:
launchFavorite→ Tara deep route +trackTaraCardTap.
- Function:
- Capture studio card (
mocapCaptureStudioflag) →handleOpenMocapStudio→ push/mocap?entry=home. - Quick actions entry (
home-quick-actions-entry, MobileMotionPressable)- Function: opens
QuickActionsTraysheet; hapticquick-actions-open. - Tray actions: core action → push href; resume/save/continue/streak/search → respective handlers; save toggles library item.
- Function: opens
Data & contracts#
- Reads: domain registry (
getShellNavigationDomains), per-domain card builders (@oshun/domain-tara|veritas|nyx|arete|nisaba), library store, current-domain store, Veritas offline cache, daypart-journey + quick-action models. All fixtures/in-memory; no network fetch on Home. - Writes:
saveOshunLibraryItem,setOshunCurrentDomain. - Realtime: none.
- Caching: Zustand-style stores; offline caches via
@/offline/*. - Auth/role check: none on Home; per-domain gating happens in target screen.
Cross-references#
- Navigation shell:
apps/oshun/mobile/app/_layout.tsx,apps/oshun/mobile/app/(tabs)/_layout.tsx. - Sibling routes: explore.md, activity.md, library.md, profile.md.
- Tab tests:
apps/oshun/mobile/app/(tabs)/index.test.ts. - Component sources:
@/components/ContinuityCard,DomainEntryHero,QuickActionsTray,RecommendationCarousel,MobileCaptureIntakeCard.
Open questions / known gaps#
-
ACTIVITY_ITEMS,TARA_FAVORITES, continuity sessions are hardcoded fixtures — confirm whether live data is wired for production builds. - No analytics on pull-to-refresh beyond haptics; confirm intended.