This page is the customer-facing inventory of where Oshun V1 is touched: the web app and its two coordinated namespaces, the phone-first mobile app, the shared shell every customer app composes from, the desktop companion, the offline substrate, and the public distribution funnel. It serves product and design leads who need the real list of what ships versus what is reachable but launch-gated, and engineers deciding which surface a customer capability belongs in. It is the feature-side companion to the architecture catalog at Product Surfaces, which documents how the same surfaces are assembled from shared libraries and the single BFF; the hub for this set is ../features.md.
The defining property of the V1 surface layer is composition over
duplication: there is one customer web app, one customer mobile app, and one
shared shell, and almost every customer-facing domain renders through those
two apps. These are real, not aspirational — every named app has its own
package.json and a substantial src/; the PWA stack is implemented and
test-covered; and the mobile apps are real Expo / Expo Router projects with
end-to-end Maestro suites and a store pipeline. Where a surface is reachable but
not yet launch-enabled (Metis) or fail-loud without credentials
(content-service), this page says so plainly rather than implying it ships.
The customer surface map#
Eight named customer-and-operator apps live under apps/oshun/, plus a separate
Metis stack under apps/metis/. Package names below were confirmed against each
app's package.json name field.
| Surface | Path | Package | Audience / role |
|---|---|---|---|
| Customer Web | apps/oshun/web/ |
@oshun/web |
Everyday and power-user customers |
| Customer Mobile | apps/oshun/mobile/ |
@oshun/mobile |
Phone-first customers |
| Oshun BFF | apps/oshun/bff/ |
@oshun/bff |
The single API front door behind both |
| Admin Web | apps/oshun/admin/ |
@oshun/admin |
Platform operators (review/safety/gov) |
| Admin Mobile | apps/oshun/admin-mobile/ |
@oshun/admin-mobile |
On-call operators |
| Tenant Console | apps/oshun/tenant-admin/ |
@oshun/tenant-admin |
Tenant admins (§20) |
| Telegram Bot | apps/oshun/telegram-bot/ |
@oshun/telegram-bot |
Messaging channel (§26) |
| Telegram Mini App | apps/oshun/telegram-miniapp/ |
@oshun/telegram-miniapp |
Embedded web channel surface (§26) |
| Content Service | apps/oshun/content-service/ |
@oshun/content-service-app |
Deployable agentic-content service (§3.2) |
| Legal (docs) | apps/oshun/legal/ |
none — markdown only | privacy-policy.md, terms-of-service.md |
Two of these entries are not described in the prose elsewhere in V1 and are worth naming explicitly, because earlier drafts of this document omitted them entirely:
apps/oshun/content-service(@oshun/content-service-app) is a real, deployable HTTP service surface — not a UI page. Itssrc/main.tsbootscreateContentHttpServer/createDurableContentServicefrom@oshun/content-serviceover a real Iris-routed creative writer and a calibrated three-memberJudgePanel(@oshun/content-quality-judge). It is deliberately fail-loud: with no model provider configured (ANTHROPIC_API_KEYabsent) it throws aNotConfiguredErrorat startup rather than fabricate generations, and its cloud deploy is honestly marked[~]in the backlog. See Isis Generation Control and Sophia Grounding for the content pipeline behind it.apps/oshun/legalis a markdown-only docs surface (privacy-policy.md,terms-of-service.md) with nopackage.json. It is the home of legal copy but not a buildable app; the marketing and landing experience itself lives in the web app underapps/oshun/web/src/app/landing/. The customer-facing privacy controls those documents describe are detailed in Privacy, Consent, Data Portability, and User Controls.
Metis is the only domain with its own app stack. Every other customer-facing domain renders through
@oshun/weband@oshun/mobilevia the shared shell. The nuance for mobile: a separateapps/metis/mobile/(@metis/mobile) exists alongsideapps/metis/{web,admin,api-gateway,worker}, so on mobile Metis is not solely the Oshun mobile app either. This is the only exception to the one-web-one-mobile rule.
The operator apps (Admin Web, Admin Mobile, Tenant Console) and the Telegram channel surfaces are covered in depth on their own pages — Admin Products — Web and Mobile, Tenant, Institution, and Operator Toolkit, and Telegram Surfaces. The rest of this page focuses on the customer experience: web, mobile, the shared shell, the desktop companion, and distribution.
Customer Web#
The customer web app (@oshun/web, a Next.js App-Router project) is the
flagship surface. V1 web includes:
- A redesigned dashboard (
src/app/page.tsx) that reflects the V1 home model and the Tara-centered product narrative — calm by default, with mixed-domain recommendations and reason labels. - A desktop-grade multi-panel workspace (
src/app/(workspace)/) for continuity, search, reading, evidence inspection, study, note taking, and assistant use. - A collapsible assistant dock with persistent context handoff from the current screen — see Assistant Experience.
- Mixed-domain recommendations with reason labels and suppression rules — see Search, Discovery, Recommendations, and Knowledge Graph.
- Domain modules for Tara ritual continuation, Arete weekly review, Veritas grounded briefing, Nyx events, Nisaba passages, and Metis study continuation.
- Universal search (
src/app/search/page.tsx) across rituals, practices, concepts, passages, claims, sources, notebooks, collections, programs, sky events, courses, lessons, and learning artifacts — with advanced filters, result grouping, saved searches, recent searches, and assistant-assisted query refinement. - Split-view reading, compare, source inspection, evidence panels, citation trails, and notebook entry points.
- A global command palette and quick-action surface for navigation, assistant invocation, search, recent items, creation actions, agent invocation, and jump-to-anything across customer surfaces.
- Multi-window and multi-tab support with per-tab continuity, draggable side panels, persistent reading and study tabs, and stable deep-link state.
- Hand-off and continuity between desktop and mobile — resumable reading, resumable study, resumable assistant transcripts, and notebook sync (the continuation state lives in Iris; see Iris Memory and Identity).
- Multi-format export, print, share-card, and embed flows for stories, claims, passages, lessons, transcripts, ritual scripts, and notebook entries where rights permit.
- A genuine PWA: install, update, relaunch, offline shell, recent-content fallback, service-worker caching, and web performance budgets (detailed below).
- Keyboard-only, accessibility, visual-regression, Lighthouse, Playwright, and resilience coverage for critical web journeys — see Analytics, Observability, Testing, and Security.
The dual-namespace pattern — and the truth about all six domains#
V1 web ships two coordinated customer-surface namespaces per domain that share BFF data and design tokens but serve distinct audiences. Both are V1, and neither is a deprecation candidate for the other — they are an intentional audience split:
/<domain>and/<domain>/*— the consumer hub plus presentational depth, the Tara-centered home for everyday customers. These are the calm Lilith-design-system "rooms" (TaraRoom,AreteRoom,VeritasRoom,NyxRoom,NisabaRoom, and the Metis surfaces), optimized for first-time and returning customers, reading, ritual continuation, and contemplative tone./domains/<domain>/*— heavier client workspaces for power users, scholars, operators in customer mode, and editorial / curation roles. Examples:/domains/arete/journal,/domains/veritas/fact-check,/domains/nyx/star-chart,/domains/tara/teachers. These are reachable from the consumer surface through deep links and context-specific entry points, but are not the canonical first read of the domain.
Correction to earlier documentation. Prior drafts claimed that "Metis and
Nisaba ship only at /<domain>/* today; their power-user surfaces are mounted
inside the consumer hub rather than at a parallel namespace." That carve-out is
stale and contradicts both the general dual-namespace pattern and the code. In
reality the /domains/* namespace covers all six domains, not four:
- The static directories under
apps/oshun/web/src/app/domains/arearete,nyx,tara, andveritas, alongside a dynamic catch-all[domainId]/and a sharedlayout.tsx(which rendersDomainPreviewBannerForPath). The catch-all is what extends coverage tonisabaandmetis. apps/oshun/web/src/navigation/routes.tsdeclaresWEB_DOMAIN_IDS = ['tara','veritas','nyx','arete','nisaba'](line 52) andWEB_NAVIGABLE_DOMAIN_IDS = [...WEB_DOMAIN_IDS, 'metis'](line 53).apps/oshun/web/src/app/domains/[domainId]/page.tsxgates onisWebNavigableDomainIdand ships per-domain SEO metadata inDOMAIN_METAfor all six ids, includingnisaba("Nisaba — Primary Texts & Scholarship") andmetis("Metis — Learning & Tutoring").apps/oshun/web/src/components/DomainRouteExperience.tsxexplicitly lists'nisaba'and'metis'(lines 66–67) and carries Metis-specific feature routing (resolveMetisFeatureRouteTarget,resolveMetisShellEntryFlowFromPath).
So /domains/nisaba and /domains/metis are reachable web routes — served
by the dynamic catch-all rather than static directories. The consumer hubs are
real too: apps/oshun/web/src/app/nisaba/ already carries deep subroutes
(compare, daily, graph, lexicon, manuscript, notebook, notebooks,
plan, scholar), and apps/oshun/web/src/app/metis/ carries assessment,
byom, courses, ingest, lesson, lessons, session, tutor, and
upload. See Nisaba — Scholarly Study and
Metis — Education and Tutoring.
Reachable route ≠ launched domain. What is true — and is a launch-status
fact, not a routing gap — is that Metis is availability: 'planned' in
libs/oshun/domain-registry/src/registry.ts, so getAvailableDomains() filters
it out of the launch-enabled set. The 2026-06-23 triage (recorded in
V1/AUDIT_2026-06-24.md) confirms the live shell's shellDomainCount drops
from 5 to 4 post-hydration when nisaba is disconnected and metis is
planned. The Metis domain route copy reflects this honestly — its description
says learner surfaces "will surface here once Metis shell launch readiness is
complete."
PWA — real, implemented, test-covered#
The web app is a genuine Progressive Web App, not a manifest stub:
apps/oshun/web/public/manifest.jsondeclaresname: "OSHUN",short_name: "OSHUN",start_url: "/?surface=pwa",scope: "/",display: "standalone"(withdisplay_overrideofwindow-controls-overlaythenstandalone), andtheme_color: "#f1ebdd"— the parchment tone of the Lilith design system. Its app shortcuts map directly to the six domains (Meditate→/domains/tara,Read→/domains/veritas,Sky Tonight→/domains/nyx,Check In→/domains/arete,Study→/domains/nisaba,Learn→/domains/metis, each with?origin=home).apps/oshun/web/public/sw.jsis the real service worker (≈20 KB).apps/oshun/web/src/lib/pwa-service-worker.tsimplements registration, update, and offline plumbing. Real exports includeregisterServiceWorker(options),applyWaitingServiceWorker(...),resolvePwaUpdateRouteContext(currentPath)(returns aPwaUpdateRouteContextwith aPwaUpdateRouteModeof'reading' | 'standard', so an update prompt offers "Keep reading" and stages the update behind the current reading flow instead of interrupting a deep-read),queueBackgroundAction(...)for background sync, andrequestServiceWorkerMemberDataClear()for privacy teardown.- Coverage lives in
apps/oshun/web/src/lib/pwa-service-worker.test.tsand the policy-levelpwa-service-worker-policy.test.ts. Performance budgets are enforced inlighthouse-budget.json.
Customer Mobile#
@oshun/mobile is a real Expo + Expo Router project, not a thin wrapper.
Oshun mobile V1 includes:
- A phone-first IA with home, domain switching, library, assistant, and profile
reachable with one-handed use. The tab layout is real Expo Router under
app/(tabs)/:index,explore,activity,library, andprofile(with_layout.tsxand co-located tests likeindex.test.tsandprofile.test.tsx). - Deep-link routing into all top-level domains and high-value object types.
app.jsonsetsexpo.scheme: "oshun",ios.bundleIdentifier: "com.oshun.mobile"(Androidpackage: "com.oshun.mobile"), and Universal-LinkassociatedDomainsincludingapplinks:oshun.app,applinks:www.oshun.app, andapplinks:app.oshun.com. Android App Links auto-verify (autoVerify: true) overpathPrefixvalues/d,/domains,/app,/home,/explore,/search,/activity, and more. - Start-of-day and return-session home behavior with quick actions for meditation, check-in, briefing, tonight, study, and assistant follow-up.
- Contextual assistant invocation from primary screens — see Assistant Experience.
- Haptic, motion, and transition behavior for major mobile flows.
- Push routing and notification controls by domain, persona, quiet hours, and sensitivity.
- Offline and retry support for recent meditations, audio assets, passages,
notes, allowed Veritas briefings, and shell continuity (on the
@oshun/offlinesubstrate described below). - Mobile continuation cards for Tara, Arete, Veritas, Nyx, Nisaba, and Metis, plus recovery-after-drift logic for habits, study, routines, and interrupted sessions.
- A mobile command surface (search / sheet / quick-action) for navigation, assistant, agent invocation, capture, and jump-to-anything.
- Hand-off to and from desktop for reading, study, journaling, voice sessions, and assistant transcripts.
- Calendar integrations (Google, Apple, Outlook) for Tara rituals, Arete reminders, Nyx events, and Metis study sessions, with two-way sync where authorized.
- Camera, microphone, and photo-library capture for journaling, evidence
uploads, source ingestion, voice notes, and assistant attachments — with
explicit permission strings in
infoPlist(NSCameraUsageDescription,NSMicrophoneUsageDescription,NSPhotoLibraryUsageDescription) and per-domain redaction policies. - Share extension targets for ingesting URLs, articles, and media into
notebooks, sources, and the assistant (declared via the iOS
CFBundleDocumentTypesforpublic.url/public.image/com.adobe.pdfandNSUserActivityTypeslikecom.oshun.mobile.share-url). - Lock screen, widgets, watch surface, and Live-Activity-style controls for
active rituals, study sessions, and voice tutoring where the platform supports
it (
NSSupportsLiveActivities: true). The wearable/widget surface is composed from@oshun/shell-wearable(see the shell section). - Mobile accessibility, crash reporting, performance, battery, memory, caching, device-matrix, and mobile E2E coverage.
The phrase "mobile E2E" understates what actually ships. Under
apps/oshun/mobile/scripts/ the real test and release tooling includes
Maestro-based end-to-end suites (run-maestro-suite.sh,
run-maestro-device-matrix.sh), Android performance gates
(validate-android-fps.sh, parse-gfxinfo.mjs), and store-submission tooling
(render-store-assets.mjs, validate-store-submission.mjs,
capture-store-submission-assets.sh), backed by EAS build/submit configuration
for the actual store pipeline.
Shared Consumer Shell#
The two customer apps above do not each reimplement navigation, the assistant,
routines, or wearable surfaces — they compose them from shell libraries under
libs/oshun/. The shared shell provides:
- Home, explore, activity, library, notifications, profile, settings, and assistant entry points.
- Domain-aware navigation for Tara, Arete, Veritas, Nyx, Nisaba, and Metis.
- Current-domain persistence, deep links, route-level analytics, feature flags, experiments, and onboarding education across all domains.
- Tara-led home ordering, blended exploration, cross-domain quick actions, and mixed-domain recommendations.
- Cross-domain activity timelines with assistant highlights, study continuation, notebook continuation, provenance state, and grounding state.
- Library support for meditations, claims, sources, passages, notebooks, collections, programs, rituals, sky events, courses, and generated artifacts.
- Notification-center behavior for mixed-domain, admin, support, study, grounding, privacy, and safety events, plus a unified message center with filters, history, delivery receipts, deep links, snooze, and unsubscribe.
- Profile and settings for account, billing entry, memory controls, disclosure, privacy, notifications, data export, data deletion, sessions, devices, locale, timezone, and personalization.
- A unified command surface (palette on web, sheet on mobile) for navigation, search, assistant, agent invocation, creation, recent items, and shortcuts.
- Universal sharing, invite, and referral flows with deep-linkable invitations, per-link permissions, attribution, expiry, and revocation.
- Public profiles for opted-in customers, creators, scholars, and teachers — with curated artifacts, audience-appropriate disclosure, follow controls, and preserved synthetic-content indicators.
- Cross-device hand-off and session continuity for reading, study, voice, assistant transcripts, ritual sessions, journaling, and authoring drafts.
- A multi-account switcher for individuals holding multiple identities (e.g. personal account and tenant-scoped account) with explicit identity indicator and isolation guarantees.
- In-app changelog / "what's new" feed, contextual help center, walkthrough overlays, keyboard-shortcut reference, in-app feedback / bug reporting / feature requests with screenshot and trace-id attachment.
- Bookmarks, reading list, saved-for-later, tasks, and queue surface with cross-domain aggregation, smart sorting, due/snooze, and resume.
- Calendar entry points with two-way sync across major providers.
- Loading, empty, offline, partial-outage, degraded, retry, and traceable BFF partial-response states.
- A banner system for tenant-, region-, or feature-scoped status messages with severity, audience scoping, locale, dismissal rules, and accessibility.
- Auth, onboarding, session refresh, re-authentication, account recovery, profile sync, cold-start personalization, and public-web-to-app conversion.
Which libraries the shell is built from#
The shell is assembled from a small set of shared libraries — see the
architecture companion page for the full lib-by-lib breakdown. The core members
are @oshun/shell-core (entry points and the command surface, e.g.
command-surface.ts, activity-timeline.ts, account-switcher.ts,
current-domain-persistence.ts, deep-links.ts), @oshun/shell-assistant (the
assistant dock and context hand-off — assistant-engine.ts, action-router.ts,
context-handoff.ts, cross-domain-continuity.ts), @oshun/shell-routines
(routine and continuation cards — routine-engine.ts, routine-recommender.ts,
step-executors.ts), @oshun/shell-wearable (the watch/widget/complication
surface — wearable-engine.ts, complication-engine.ts,
active-session-surfaces.ts, haptic-patterns.ts), @oshun/navigation, and
the design system (@oshun/design-tokens, @oshun/ui).
Two real shell libraries earlier docs omitted. That composition list looked exhaustive but was not — two additional real, code-bearing shell libraries exist and represent surface capabilities neither legacy doc named:
@oshun/shell-desktop(libs/oshun/shell-desktop/) is an entire Electron-class desktop companion surface — a whole surface category that goes unmentioned in the source feature list. Itssrc/containsdesktop-engine.ts(DesktopEngine),window-manager.ts(WindowManager),tray-companion.ts(buildTrayMenu,computeTrayIconState),protocol-handler.ts(ProtocolHandler,buildDeepLink,buildShellLink),update-manager.ts(UpdateManager),widget-engine.ts(WidgetEngine,getWidgetTemplate),notification-bridge.ts(NotificationBridge,buildStreakAtRiskNotification,buildDailySummaryNotification), andshortcut-manager.ts(ShortcutManager,normalizeAccelerator). In plain terms: window/tray lifecycle, OS-level protocol (deep-link) handling, an auto-update path, desktop widgets, native notification bridging, and global shortcuts.@oshun/shell-achievements(libs/oshun/shell-achievements/) supplies the cross-domain accomplishment layer. Itssrc/containsachievement-engine.ts(AchievementEngine,InMemoryAchievementStore),achievement-definitions.ts(getAchievementsByDomain,getCrossDomainAchievements,getSecretAchievements),challenge-templates.ts(getChallengesByDomain,getCrossDomainChallenges), andsocial-accountability.ts(analyzePartnershipHealth,computeCheckInSchedule,computeEngagementScore,generateAccountabilityInsights).
Offline substrate — @oshun/offline#
The PWA and mobile offline behavior is not bespoke per app — it rides on the
real @oshun/offline library (libs/oshun/offline/), which the legacy
shell-composition list also omitted. Its src/index.ts re-exports types,
storage, cache, retry, queue, and connectivity. The concrete building
blocks are the OfflineSyncQueue class (queue.ts) and the OfflineCache
class (cache.ts), over typed contracts SyncQueueItem<TPayload>,
RetryPolicy, and ConnectivityState (types.ts). This is the substrate the
service worker's queueBackgroundAction and the mobile recovery-after-drift
logic both lean on, so offline retry and sync behave consistently across web and
mobile.
One route map, six domains#
Deep links and per-platform paths are defined once in
libs/oshun/navigation/src/routes.ts and consumed by every surface. The scheme
is fixed (OSHUN_SCHEME = 'oshun'), and the domain block of OSHUN_ROUTE_MAP
maps all six domains uniformly to a webPath, a mobilePath, and a
deepLinkBase (lines 96–129):
| Domain | webPath |
mobilePath |
deepLinkBase |
|---|---|---|---|
| tara | /domains/tara |
/domains/tara |
oshun://tara |
| veritas | /domains/veritas |
/domains/veritas |
oshun://veritas |
| nyx | /domains/nyx |
/domains/nyx |
oshun://nyx |
| arete | /domains/arete |
/domains/arete |
oshun://arete |
| nisaba | /domains/nisaba |
/domains/nisaba |
oshun://nisaba |
| metis | /domains/metis |
/domains/metis |
oshun://metis |
That nisaba and metis carry the same shape as the other four is the
navigation-layer corroboration that the /domains/* namespace is genuinely
six-wide. A single edit to routes.ts keeps web links, mobile tab paths
(OSHUN_TAB_PATHS), and deep links coherent — which is exactly why a new domain
becomes routes plus a DomainRouteExperience branch, not a new application. The
full assembly story is in the architecture companion at
Product Surfaces.
Public Web and Distribution#
V1 includes the public distribution surface:
- A public marketing website with product positioning, conversion paths, and
semantic SEO. Marketing / landing lives at
apps/oshun/web/src/app/landing/; legal copy lives at the markdown-onlyapps/oshun/legal/. - Open Graph, social-sharing metadata, preview assets, and public-to-auth
app funnel tracking (per-domain OG images such as
/og/domain-<id>.pngare emitted fromDOMAIN_METAin the[domainId]route). - Apple App Store and Google Play submission assets, listing content,
screenshots, privacy labels, and review preparation — wired through the
render-store-assets.mjs/validate-store-submission.mjsmobile tooling. - Universal Links, Android App Links, TestFlight, Play Store internal/beta
testing, a minimum-version strategy, forced-update rules, and external
deep-link E2E coverage — the App-Links side declared in
app.jsonassociatedDomains(iOS) and the auto-verifiedintentFilters(Android).
Why it works this way#
- One web app, one mobile app, one shell. Centralizing navigation, the
assistant, routines, achievements, and the offline substrate in
libs/oshun/shell-*and@oshun/offlinemeans adding a domain is a routing and experience change, not a new app. The six-wideroutes.tsmap is what keeps a single deep-link edit coherent across web, mobile, and the BFF. - Reachability and launch status are separate concerns. A
/domains/<id>route can exist and render while the domain registry still reports the domain asbetaorplanned. Encoding launch state indomain-registry/src/registry.ts(and filtering it viagetAvailableDomains()) keeps the routing layer honest: the shell can show fewer domains post-hydration without any route being deleted. - Fail loud over fake. The
content-servicesurface throwsNotConfiguredErrorrather than fabricate generations when no provider is configured, and its cloud deploy is honestly marked[~]. That candor is the intended posture across surfaces — a reachable-but-gated surface says so rather than pretending to ship.
Related#
- Product Surfaces — the architecture-side catalog of how these surfaces are assembled from shared libs and the BFF.
- V1 Product Promise — the launch-configuration framing (five enabled domains, Metis visible-but-planned).
- Assistant Experience — the dock and command-surface capabilities the shell composes.
- Admin Products — Web and Mobile and Tenant, Institution, and Operator Toolkit — the operator surfaces split out of the customer apps.
- Telegram Surfaces and WhatsApp, Email, Push, SMS, Discord, and Slack — the channel surfaces beyond web and mobile.
- Architecture, Platform Foundations, and Security — the BFF and platform layer behind every surface.