V1 Web PWA · Surface walkthrough

Home

A per-surface walkthrough of the V1 Web PWA customer surface: layout, states, interactions, data, and cross-references.

walked
9sections12 minread

On this page

Context. surface customer · domain home · route / · auth signed-in (anonymous → redirected to /welcome) · source apps/oshun/web/src/app/page.tsx

Last walked. 2026-06-27 automated coverage reconciliation — existing Playwright and component coverage mapped for authenticated and anonymous entry, PWA relaunch, warm offline route availability, domain-unavailable routing, Home workspace regions, Tara/Arete/Veritas/Nyx/Nisaba/Metis continuations, daypart journeys, direct domain launches, quick actions, mixed recommendations, companion bridges, multi-device sync, and activity feed. Earlier 2026-05-29 runtime walk verified render, /v1 data (2xx), console/page-errors, expected content, and screenshot. Remaining gaps are listed below.

Purpose#

Today's start. Tara-centered, with recommendations across all six domains, the user's domain launch list, daypart-aware journey rails, and a shell-wide search affordance. See V1/features.md for the home surface scope.

Entry points#

  • Shell nav: Home (g h / index 1) — primary entry from any other route
  • Mobile bottom nav: Home tab — index 0
  • Cold-start signed-in — middleware lands here after sign-in if no ?next=
  • PWA relaunch target — when no other target persisted
  • Domain unavailable redirect?unavailableDomain=<id>&unavailableReason=<reason> surfaces a notice inline
  • Direct URL / bookmark — yes (auth required)

Layout regions#

page.tsx mounts ShellLayout with active="home" and a single breadcrumb. Inside, HomeWorkspace composes the home surface.

  • Header: shell header — Home active
  • Resume banner: OnboardingResumeBanner when user has unfinished onboarding
  • Anchor context rail: HomeAnchorContextRail
  • Tara ritual continuation: HomeTaraRitualContinuationSection
  • Veritas briefing: HomeVeritasBriefingSection
  • Nisaba continuation: HomeNisabaContinuationSection
  • Metis study continuation: HomeMetisStudyContinuationSection
  • Daypart rail: DaypartJourneyRail
  • Domain launch list: HomeDomainLaunchList
  • Quick actions rail: HomeQuickActionsRail
  • Mixed recommendations: MixedDomainRecommendationsLane
  • Multi-device continuity: HomeMultiDeviceContinuityPanel
  • Companion bridge: HomeCompanionBridgeRail
  • Companion sections: HomeCompanionSections
  • Footing summary strip: HomeFootingSummaryStrip
  • Activity feed: ActivityFeed
  • Continuation telemetry bridge: HomeContinuationTelemetryBridge (no UI, instrumentation)

The legacy KpiGrid component itself is not mounted by HomeWorkspace. The live home KPI surface is HomeFootingSummaryStrip, which emits [data-kpi-grid] under the Daily footing region. DomainCardGrid remains preview/scaffolding-only rather than part of the live home composition.

States#

  • Loading — skeletons for each rail; no CLS; preserves layout
  • Anonymous user — middleware redirects to /welcome (never sees /). Covered by apps/oshun/web/e2e/pwa-smoke.spec.ts public root coverage.
  • First-time signed-in userOnboardingResumeBanner visible if onboarding incomplete. Covered at component level by apps/oshun/web/src/components/home/__tests__/OnboardingResumeBanner.test.tsx.
  • Returning user, full data — all live V1 rails populate. Covered by apps/oshun/web/e2e/home-dashboard-flow.spec.ts.
  • Returning user, sparse data — selected empty/fallback states are covered, but an all-rails sparse fixture still needs a route-level pass.
  • Domain unavailable?unavailableDomain=<id>&unavailableReason=<reason> keeps Home usable, filters blocked recommendations, marks launch cards/switcher entries, and routes status-first. Covered by home-tara-centering-continuity.spec.ts, shell-domain-unavailable-fallback.spec.ts, and the Home continuation component tests.
  • Error (recoverable) — rail/API failures render honest fallback, unavailable, or partial-outage states instead of fabricated data. Covered by home-arete-practice.spec.ts, home-veritas-briefing.spec.ts, home-nyx-perspective.spec.ts, home-nisaba-continuation.spec.ts, home-mixed-domain-recommendations.spec.ts, and ActivityFeed.test.tsx.
  • Error (unrecoverable)error.tsx at segment level catches; reset button works
  • Offline (warm cached shell) — after authenticated warmup, / remains route-available offline. Covered by apps/oshun/web/e2e/offline-shell-routes.spec.ts.
  • Offline rail placeholders / cold Home load — uncached rail behavior and cold offline Home boot still need route-specific assertions.
  • Standalone PWA — authenticated standalone relaunch restores the last route; unauthenticated standalone relaunch goes through welcome with the saved redirect. Covered by apps/oshun/web/e2e/pwa-smoke.spec.ts.
  • PWA cold start with relaunch targetpendingLaunchTarget resolves and redirects. Covered by pwa-smoke.spec.ts.
  • Reduced motion — component-level animation guards exist on several rails, but Home still needs a route-level reduced-motion pass.

Interactions#

Header / shell#

Covered globally in shell/01-app-shell.md; home-specific interactions only here.

Onboarding resume banner#

  • "Resume onboarding" (button)
    • Function: navigates to /onboarding?mode=resume
    • Keyboard: Enter activates; included in tab order
    • Screen reader: button label is "Resume onboarding"; copy identifies the last saved step
    • Touch target: ≥ 44×44 px
    • Mobile: full-width banner; no horizontal scroll
    • Disabled when: onboarding complete (banner hidden, not disabled)
    • Offline behavior: routes to cached onboarding if available
    • Covered by OnboardingResumeBanner.test.tsx
  • "Dismiss" (icon button)
    • Not part of the current V1 component; add only if product wants a session-scoped dismiss affordance.

Tara ritual continuation section#

  • Primary ritual action (native link)
    • Function: opens the recent Tara session when continuity exists; otherwise opens the daypart preset.
    • Keyboard / SR / touch: native anchor semantics; route-level keyboard activation covered.
    • Offline behavior: route-level offline cached shell is covered; pinned transcript/audio behavior remains a Tara-player concern.
    • Telemetry: home_continuation_clicked through shared continuation attributes.
    • Covered by HomeTaraRitualContinuationSection.test.tsx, home-tara-centering-continuity.spec.ts, and home-continuation-analytics.spec.ts.
  • "Browse sessions" (secondary link)
    • Function: navigates to /domains/tara?origin=home&path=%2Fmeditate%2Fsessions.
    • Covered by HomeTaraRitualContinuationSection.test.tsx.
  • Unavailable-domain primary action — preserves status-first routing with unavailable=1, reason, path, and ref. Covered by HomeTaraRitualContinuationSection.test.tsx and home-tara-centering-continuity.spec.ts.

Veritas briefing section (HomeVeritasBriefingSection, aria-label="Veritas briefing")#

  • Live briefing primary reader action — opens the grounded reader from Home. Covered by HomeVeritasBriefingSection.test.tsx and apps/oshun/web/e2e/home-veritas-briefing.spec.ts.
  • Endpoint outage fallback / Ask action — shows honest unavailable copy with no fabricated claim and routes to Veritas Ask. Covered by HomeVeritasBriefingSection.test.tsx and home-veritas-briefing.spec.ts.
  • Unavailable-domain primary action — preserves status-first routing with unavailable=1, reason, reader path, and ref. Covered by HomeVeritasBriefingSection.test.tsx and home-veritas-briefing.spec.ts.
  • Trending / claims / sources full action sweep — component renders these action targets, but the route-level Home spec currently clicks only the primary reader and fallback Ask paths.

Nisaba continuation section (HomeNisabaContinuationSection, aria-label="Nisaba continuation")#

  • Live primary / library / notebook / support actions — each router.push(...) to its Nisaba action href. Covered by apps/oshun/web/e2e/home-nisaba-continuation.spec.ts, which primes the authenticated shell, seeds a real /v1/nisaba/notebooks record through the BFF, verifies the browser reads that exact notebook card from /v1/nisaba/notebooks?status=active, and clicks the notebook, library, support, and primary passage actions.
  • Unavailable-domain primary action — preserves status-first routing with unavailable=1, reason, passage path, and ref. Covered by home-nisaba-continuation.spec.ts with the same real BFF notebook seed.
  • Endpoint outage fallback — daily passage and notebook endpoint failures render the curated fallback thread and route to the fallback passage. Covered by home-nisaba-continuation.spec.ts.
  • Real daily-passage seed writer — not exposed for this Home scenario; the spec keeps a deterministic GET /v1/nisaba/passages/daily fixture for Yoga Sutra 1.2 while the notebook continuation uses real BFF write/read infrastructure.

Metis study continuation section#

  • Primary resume action — opens the strongest saved Metis return. Covered by HomeMetisStudyContinuationSection.test.tsx; the browser route handoff from Home into /domains/metis?origin=home&path=%2Fcourses is covered by metis-lesson-completion.spec.ts.
  • Curated course/assessment fallback — routes to the curated assessment path when there are no saved Metis items. Covered by HomeMetisStudyContinuationSection.test.tsx.
  • Unavailable-domain primary action — preserves status-first routing with unavailable=1, reason, assessment path, and ref. Covered by HomeMetisStudyContinuationSection.test.tsx.

Daypart journey rail#

DaypartJourneyRail.tsx

  • Current daypart summary — resolves the active arc from local hour or onboarding routine preference and exposes the current action. Covered by DaypartJourneyRail.test.tsx and apps/oshun/web/e2e/daypart-journey-home.spec.ts.
  • Journey cards/list — renders the canonical morning, midday, and evening journeys and marks the active one. Covered by DaypartJourneyRail.test.tsx and daypart-journey-home.spec.ts.
  • Journey step actions — route and assistant actions hand off to concrete shell/domain destinations; one route handoff is clicked at E2E level. Covered by DaypartJourneyRail.test.tsx, daypart-journey-home.spec.ts, and home-continuation-analytics.spec.ts.
  • Keyboard roving / tablist behavior — not applicable to the current list implementation, but no explicit keyboard traversal spec exists yet.
  • Reduced motion route check — no autoplay is present, but a prefers-reduced-motion Home route assertion is still pending.

Domain launch list#

  • Each domain item (button-like card)
    • Function: navigates to canonical domain route
    • Keyboard: Enter / Space route through the same handler
    • SR: aria-label combines the domain label with the launch summary
    • Covered by HomeDomainLaunchList.test.tsx, home-dashboard-flow.spec.ts, and home-domain-narrative-order.spec.ts.
  • Unavailable domain item — marks the card, shows the reason, and routes status-first. Covered by HomeDomainLaunchList.test.tsx and shell-domain-unavailable-fallback.spec.ts.
  • Reorder handle — not present in current Home V1; personalized ordering comes from onboarding/preferences rather than in-place drag-and-drop.
  • Add/remove domain — not present in current Home V1; settings/profile domain preference management is outside this surface.

Domain card grid (preview-only)#

DomainCardGrid is not rendered on the live home surface (preview scaffolding only); direct domain launches ship via DomainSwitcherEntryPanel and HomeDomainLaunchList. Documented here for the preview/skeleton state:

  • Six cards: Tara, Arete, Veritas, Nyx, Nisaba, Metis
    • Each navigates to its domain root
    • SR announces domain + tagline
    • Marks unavailable domains with data-domain-unavailable, removes the engagement/actions preview, and routes status-first
    • Covered by DomainCardGrid.test.tsx; live Home route launch behavior is covered through HomeDomainLaunchList instead.

Quick actions rail#

HomeQuickActionsRail.tsx

  • Each action button — six fixed journeys render in Tara, Arete, Veritas, Nyx, Nisaba, Metis order with daypart-aware hrefs and status-first unavailable routing. Covered by HomeQuickActionsRail.test.tsx and apps/oshun/web/e2e/home-quick-actions.spec.ts.

CrossDomainQuickActionsMenu is not rendered by the home quick-actions rail — it lives in ShellLayout and ExploreDashboard.

Mixed recommendations lane#

  • Recommendation cards (link) — live and fallback slates render in Tara-centered, onboarding-guided, preference-aware, or Tara-theme order; primary links route through hydrated domain paths. Covered by MixedDomainRecommendationsLane.test.tsx, CrossDomainRecommendations.test.tsx, home-mixed-domain-recommendations.spec.ts, and home-mixed-domain-recommendations-analytics.spec.ts.
  • Why copy / reason badges — cards render explanation copy, source-context labels, fit tiers, and reason badges such as Good timing, Practice handoff, Grounded context, Perspective handoff, Passage companion, Source lineage, Study companion, Sky to text, and Because you saved. Covered by the recommendation unit and E2E specs.
  • Feedback controls — "More like this", "Less like this", and "Hide" preserve the current card, show future-feedback copy, emit telemetry, and POST feedback. Covered by CrossDomainRecommendations.test.tsx.
  • End of lane — "Show more" / "Show fewer" expands from four to six cards. Covered by recommendation unit tests and home-mixed-domain-recommendations.spec.ts.

Multi-device continuity panel#

  • Sync health signals — shows profile/preference sync status and phone + web continuity copy without advertising unbuilt watch/glance capability. Covered by HomeMultiDeviceContinuityPanel.test.tsx and visible in home-dashboard-flow.spec.ts.
  • "Open sync controls" — links to /profile as the control surface. Covered by HomeMultiDeviceContinuityPanel.test.tsx.
  • "Refresh sync" — appears when sync is delayed and calls refresh({ force: true }). Covered by HomeMultiDeviceContinuityPanel.test.tsx and the Home panel status case in multi-device-handoff-deepening.spec.ts.
  • Active device session management — handled under Profile/auth flows, not the Home panel.
  • Offline disabled state — Home panel sync-delay behavior is covered; a Home-specific offline disabled-state assertion is still pending.

Companion bridge rail#

  • Domain companion bridge cards — renders Arete, Veritas, Nyx, Nisaba, and Metis in canonical/current-preference order with journey-aware action hrefs. Covered by HomeCompanionBridgeRail.test.tsx, home-tara-centering-continuity.spec.ts, and home-domain-narrative-order.spec.ts.
  • Unavailable companion bridge — marks unavailable domains and routes to status-first launches with reason/ref. Covered by HomeCompanionBridgeRail.test.tsx and home-tara-centering-continuity.spec.ts.
  • Mobile app / Telegram CTAs — not part of the current Home companion bridge rail; /welcome/download is covered by PWA install smoke instead.

Activity feed#

  • Item list — recent cross-domain activity renders with domain tags, icon, color strip, relative timestamp, and empty state. Covered by ActivityFeed.test.tsx and home-dashboard-flow.spec.ts.
  • Item action click → source surface. Covered by home-dashboard-flow.spec.ts.
  • Filter (all / mentions / system) — no filter tablist exists in the current V1 Home feed.
  • "View all"/activity. Covered by ActivityFeed.test.tsx.
  • Realtime updates — the current feed fetches once and refreshes relative timestamps every 30s; new-item push/polling is not implemented here.
  • Hydration-safe timestamps — timestamp rendering starts from an SSR-safe sentinel and then updates on the client. Covered by ActivityFeed.test.tsx relative timestamp assertions.

Automated Coverage#

  • Route-level Home workspace: apps/oshun/web/e2e/home-dashboard-flow.spec.ts, home-tara-centering-continuity.spec.ts, home-quick-actions.spec.ts, daypart-journey-home.spec.ts, home-domain-narrative-order.spec.ts, and the Arete / Veritas / Nyx / Nisaba Home continuation specs cover the populated authenticated surface, direct launches, daypart routes, continuation actions, companion order, and domain-unavailable status-first behavior.
  • Recommendation lane: home-mixed-domain-recommendations.spec.ts, home-mixed-domain-recommendations-analytics.spec.ts, MixedDomainRecommendationsLane.test.tsx, and CrossDomainRecommendations.test.tsx cover live/fallback ordering, suppression rules, saved-source labels, Show more, primary route taps, impressions, taps, and feedback POSTs.
  • PWA/offline/auth shell: pwa-smoke.spec.ts, offline-shell-routes.spec.ts, and shell-domain-unavailable-fallback.spec.ts cover anonymous root redirect, standalone relaunch, warm offline Home availability, real SW fallback, and Home continuity when a domain is unavailable.
  • Component rails: Home component tests cover onboarding resume, Tara, Veritas, Metis, quick actions, daypart journeys, domain launch list, companion bridge rail, multi-device continuity, and activity feed behavior.

Data & contracts#

  • Reads: ActivityFeed calls buildOshunBffUrl('/v1/activity', { limit: 5 }). Home domain rails also fetch their own BFF endpoints; verified examples include Nisaba's real /v1/nisaba/notebooks?status=active browser read in home-nisaba-continuation.spec.ts after the test seeds a BFF notebook. The daily Nisaba passage remains fixture-backed in that spec because no deterministic daily-passage writer is exposed for Home setup.
  • Writes: recommendation feedback posts to /v1/recommendations/feedback; continuation clicks/impressions emit browser analytics. No Home-level onboarding dismiss, domain reorder, or "not for me" write exists in the current V1 surface.
  • Realtime: activity feed fetches once on mount and refreshes relative timestamps every 30s; live new-item push/polling is not implemented on Home.
  • Caching: SSR'd with dynamic = 'force-dynamic' (per page.tsx); individual rails SWR within client
  • Auth/role check: middleware redirects anonymous to /welcome

Cross-references#

Open questions / known gaps#

  • Confirm exact set of rails that ship on day-1 vs. behind feature flag. HomeWorkspace currently mounts the V1 rail set documented above, and home-dashboard-flow.spec.ts asserts the explicit region model.
  • Document the recommendation engine's surface contract (input + ranking signals). The Home lane has strong behavioral coverage, but the contract itself still needs a canonical architecture note.
  • Snapshot expected layout at each breakpoint (320 / 390 / 640 / 1024 / 1440). Current automation covers 375 / 768 / 1180 / 1440 plus desktop/laptop topography, but not the exact breakpoint matrix listed here.