Architectural overview of the Oshun platform shell (
libs/oshun/): the domain registry, the typed domain-adapter and embodiment-adapter pattern, assistant orchestration, and multi-surface shell design.
The Oshun shell domain is the platform's user-facing integration layer. It sits above every product-domain implementation (Tara, Veritas, Nyx, Arete, Nisaba, Metis) and above every AI subsystem (Psyche, Aja, Sophia, Iris, Isis, Lilith). Its job is to tie all of those systems into a single, coherent product experience without letting any one domain's implementation details leak into application code.
New engineers should think of Oshun as the glue layer: it does not contain meditation sessions, news articles, or stargazing data — those live in their respective product-domain services. Instead, Oshun defines how any surface (web, mobile, desktop, wearable) discovers, launches, and communicates with those services, and how the voice/text assistant routes user intent across them.
The shell is structured around four responsibilities: providing typed domain adapters so the rest of the application never writes raw HTTP calls to a domain service; providing an assistant orchestration engine that routes user utterances to the right domain; maintaining a shared UI and design system that keeps the product visually consistent; and supplying cross-surface shell logic (auth, offline sync, navigation, analytics, achievements, routines) that every platform surface needs but should not independently implement.
Role of the Oshun Shell Domain#
The Oshun shell domain is the platform's user-facing integration layer. It sits above all domain implementations and provides:
- Typed domain adapters — Each domain API is wrapped in a strongly-typed TypeScript adapter that the shell and applications use. Direct HTTP calls to domain APIs do not appear in application code. When a domain API changes, only its adapter needs updating; TypeScript catches breakage at compile time everywhere the adapter is consumed.
- Assistant orchestration — The
@oshun/shell-assistantlibrary routes voice and text intents to the correct domain adapters. Users interact with one assistant, not six separate apps. - Shared UI system — Design tokens, UI primitives, and navigation contracts used across all Oshun surfaces. A button or card component is authored once and deployed everywhere.
- Cross-surface shell logic — Desktop, mobile, and wearable shells share core logic (auth, offline, navigation, analytics) and differ only in presentation.
Architecture Diagram#
The diagram below shows the four tiers of the Oshun shell, from the user-facing surfaces at the top to the domain API servers at the bottom. Each tier depends only on what is directly below it; surfaces never call domain servers directly.
┌─────────────────────────────────────────────────────────────────────────────┐
│ USER SURFACES │
│ apps/oshun/web apps/oshun/mobile @oshun/shell-desktop │
│ @oshun/shell-wearable │
└───────────────────────────────────┬─────────────────────────────────────────┘
│
┌───────────────────────────────────┼─────────────────────────────────────────┐
│ SHELL ORCHESTRATION │
│ @oshun/shell-core @oshun/shell-assistant @oshun/navigation │
│ @oshun/shell-routines @oshun/shell-achievements @oshun/analytics │
│ @oshun/offline │
└──────────────────────┬────────────────────────────┬────────────────────────┘
│ │
┌──────────────────────▼─────────────┐ ┌─────────▼─────────────────────────┐
│ DOMAIN ADAPTERS │ │ EMBODIMENT ADAPTERS │
│ @oshun/domain-registry (catalog) │ │ @oshun/embodiment-psyche │
│ @oshun/domain-tara │ │ @oshun/embodiment-aja │
│ @oshun/domain-veritas │ │ @oshun/evidence-sophia │
│ @oshun/domain-nyx │ │ @oshun/memory-iris │
│ @oshun/domain-arete │ │ @oshun/generation-control-isis │
│ @oshun/domain-nisaba │ │ @oshun/persona-policy-lilith │
│ @oshun/domain-metis │ └────────────────────────────────────┘
└──────────────────────┬─────────────┘
│
┌──────────────────────▼─────────────────────────────────────────────────────┐
│ SHARED INFRASTRUCTURE │
│ @oshun/auth-client @oshun/ui @oshun/design-tokens │
│ @oshun/color-science @oshun/types @oshun/contracts │
└──────────────────────┬─────────────────────────────────────────────────────┘
│
│ apps/oshun/bff aggregates domain REST responses
▼
Domain API Servers (Tara, Veritas, Nyx, Arete, Nisaba, Metis)
@oshun/domain-registry is the static domain catalog, not an adapter; it is
grouped with the domain adapters because they all concern product domains.
libs/oshun/ additionally contains operator/tenant, customer-support,
messaging, search-discovery, persistence, i18n, privacy, trust-safety, and
agentic-studio libraries that are outside the core shell surface shown above.
Library Organization#
The source of truth for library structure is the libs/oshun/ directory. The
tree below shows the logical groupings; each entry corresponds to a directory
and an npm package:
libs/oshun/
│
├── DOMAIN REGISTRY + ADAPTERS
│ ├── domain-registry/ → @oshun/domain-registry (Domain catalog + metadata + guards)
│ ├── domain-tara/ → @oshun/domain-tara (Tara API client + canonical adapter)
│ ├── domain-veritas/ → @oshun/domain-veritas (Veritas API client + canonical adapter)
│ ├── domain-nyx/ → @oshun/domain-nyx (Nyx API client + canonical adapter)
│ ├── domain-arete/ → @oshun/domain-arete (Arete API client + canonical adapter)
│ ├── domain-nisaba/ → @oshun/domain-nisaba (Nisaba read adapter)
│ └── domain-metis/ → @oshun/domain-metis (re-export of @metis/api-client)
│
├── EMBODIMENT ADAPTERS
│ ├── embodiment-psyche/ → @oshun/embodiment-psyche (Voice/avatar session contracts)
│ ├── embodiment-aja/ → @oshun/embodiment-aja (Embodied-instruction contracts)
│ ├── evidence-sophia/ → @oshun/evidence-sophia (Grounded evidence retrieval)
│ ├── memory-iris/ → @oshun/memory-iris (Memory continuity contracts)
│ ├── generation-control-isis/ → @oshun/generation-control-isis (Generation control plane)
│ └── persona-policy-lilith/ → @oshun/persona-policy-lilith (Persona policy + safety)
│
├── SHELL SERVICES
│ ├── shell-core/ → @oshun/shell-core (Shell runtime + home orchestration)
│ ├── shell-assistant/ → @oshun/shell-assistant (Intent classification + routing)
│ ├── shell-achievements/ → @oshun/shell-achievements (Cross-domain achievements)
│ ├── shell-routines/ → @oshun/shell-routines (Tara/Arete routine engine)
│ ├── shell-desktop/ → @oshun/shell-desktop (Desktop shell features)
│ └── shell-wearable/ → @oshun/shell-wearable (Wearable shell surface)
│
├── CROSS-CUTTING CONCERNS
│ ├── analytics/ → @oshun/analytics (Typed analytics events)
│ ├── auth/ → @oshun/auth-client (Client-side auth and session)
│ ├── navigation/ → @oshun/navigation (Route contracts + link helpers)
│ └── offline/ → @oshun/offline (Storage cache + sync queue)
│
└── SHARED UI
├── ui/ → @oshun/ui (Shared UI primitives)
├── design-tokens/ → @oshun/design-tokens (Tokens and semantic themes)
└── color-science/ → @oshun/color-science (ACES color pipeline)
libs/oshun/ also contains operator/tenant, customer-support, messaging,
search-discovery, persistence, i18n, privacy, trust-safety, persona-registry,
agent-pipelines, and agentic-studio libraries beyond the core shell surface.
Domain Adapter Pattern#
The domain adapter pattern is the key architectural decision in the Oshun shell.
Rather than letting every application screen call a domain's REST API directly,
all domain access is channeled through a typed adapter library. This provides a
single upgrade seam: when the Tara API changes its response shape, only
@oshun/domain-tara needs updating, and TypeScript immediately flags any
incompatibilities across all consumers.
Each product-domain adapter follows the same two-layer structural pattern:
@oshun/domain-nyx/
src/
types.ts ← raw *ApiAdapter interface + domain types/enums + error class
client.ts ← typed HTTP client implementing *ApiAdapter (runtime-agnostic fetcher)
domain-adapter.ts ← canonical adapter interface, versioned contract, search/launch helpers
canonical-adapter.ts ← factory wrapping the API adapter into the canonical adapter
card-model.ts ← shell-facing surface card models
launch-actions.ts ← typed launch actions
deep-links.ts ← domain deep-link builders
*-relationship.ts ← cross-domain bridge helpers
index.ts ← public API exports
The API adapter (*ApiAdapter, implemented by client.ts) mirrors the
domain REST API. The canonical adapter wraps it and adds shell-facing
concerns: a versioned contract descriptor (buildOshunContractVersionDescriptor
from @oshun/types), registry metadata, an availability check, home-card
composition, search, launch resolution, and cross-domain bridge helpers.
The adapter is the single source of truth for how the shell interacts with a domain API. Changing a domain's API requires updating only the adapter — all consumers of the adapter are insulated from the change.
The audited adapters (Tara, Veritas, Nyx, Arete) bundle a typed HTTP client and
raise a domain-specific error class (NyxDomainAdapterError, etc.) with a
code of http | network | parse. The Nisaba adapter is read-oriented and
exposes role-scoped views (shell / admin / assistant). The
@oshun/domain-metis library re-exports @metis/api-client rather than
defining its own client, because Metis maintains its own API client package.
Shell Assistant Architecture#
The assistant turns spoken or typed requests into domain actions. Its
architecture deliberately keeps the intent classification rule-based and
domain-agnostic at the engine level, delegating domain-specific knowledge to
per-domain Assistant*Adapter instances that are injected at runtime.
The flow from user utterance to rendered response follows these steps:
User utterance (voice or text)
│
▼
@oshun/shell-assistant — AssistantEngine
│
▼
IntentResolver
│ → ResolvedIntent { category, name, domain, confidence, slots }
▼
ActionRouter (domain-keyed AssistantDomainAdapters)
│
├── domain='tara' → AssistantTaraAdapter
├── domain='veritas' → AssistantVeritasAdapter
├── domain='nyx' → AssistantNyxAdapter
├── domain='arete' → AssistantAreteAdapter
├── domain='nisaba' → AssistantNisabaAdapter
├── domain='metis' → AssistantMetisAdapter
│
└── confidence < intentConfidenceThreshold → clarification
│
▼
ResponseFormatter → AssistantResponse { text, cards, suggestedActions, navigateTo }
│
▼
Shell UI renders response + optional navigation target
The assistant package depends only on @oshun/domain-registry,
@oshun/embodiment-psyche, and @oshun/memory-iris. The IntentResolver is
rule-based over the per-domain intent definitions (TARA_INTENTS, etc.); it
does not embed an LLM client in the library. An Iris memory bridge and a Psyche
session bridge connect the assistant to memory continuity and voice/avatar
sessions, keeping those AI-subsystem concerns out of the engine's own code.
Multi-Surface Architecture#
A key design goal is that business logic — routing, intent classification, domain calls, achievement tracking — is written once in shared libraries and deployed to every surface. Only the presentation layer differs between platforms.
The same domain adapter and shell service libraries are shared across surfaces. Only the presentation layer differs:
| Surface | App / Library | Rendering | Primary Input |
|---|---|---|---|
| Web | apps/oshun/web |
React | Keyboard/mouse/touch |
| Mobile | apps/oshun/mobile |
React Native | Touch + voice |
| Desktop | @oshun/shell-desktop (shell lib) |
React | Keyboard/mouse |
| Wearable | @oshun/shell-wearable (shell lib) |
Minimal React | Voice + haptic |
Shared across surfaces: @oshun/shell-core, @oshun/analytics,
@oshun/auth-client, @oshun/navigation, @oshun/offline,
@oshun/design-tokens, and the domain and embodiment adapters.
Offline Architecture (@oshun/offline)#
The offline layer ensures that users can still read content and queue mutations even when they lose network connectivity. It uses an optimistic-update pattern: actions are recorded immediately to a durable queue and replayed when the network returns.
User performs action while offline
│
▼
@oshun/offline SyncQueue records operation
│
App shows optimistic update in UI
│
Network reconnects
│
▼
SyncQueue replays operations in order
│
├── Success → confirm UI state, clear queue entry
└── Conflict → apply resolution strategy, surface to user if needed
Design Principles#
These four principles reflect deliberate decisions made during the Oshun shell design, not general advice. Each principle has a consequence that constrains how new code should be written.
- Adapters own the domain API contract — No application code calls domain APIs directly. All calls go through typed adapters. Consequence: a new domain feature requires a new adapter method before any UI can use it.
- Assistant session state is pluggable — The
@oshun/shell-assistantengine holds session state through aSessionStoreinterface;InMemorySessionStoreis the bundled default. Durable user-level memory is owned by Iris and reached through the assistant's Iris memory bridge. Consequence: swapping in a Redis-backed session store requires only implementingSessionStore, not touching engine logic. - Surfaces share logic, differ in presentation — Business logic (routing, intent classification, domain calls) lives in shared libraries. Surface-specific code is only layout and interaction patterns. Consequence: a bug fix or behavioral change in intent classification fixes all surfaces simultaneously.
- Progressive enhancement — Features degrade gracefully when a domain API
is unavailable. The domain registry's
isAvailable()check gates feature presentation. Consequence: a domain can be taken offline for maintenance without breaking the rest of the shell.
Cross-Domain Dependencies#
The Oshun shell itself is a consumer of shared infrastructure — it does not
re-implement primitives that live in libs/shared/ and libs/contracts/. The
boundary exists so that primitive types and contract envelopes can be shared
across the Oshun shell, domain service layers, and other parts of the monorepo
without circular dependencies.
The Oshun shell libraries depend on shared infrastructure packages:
| Dependency | Purpose |
|---|---|
@oshun/types (libs/shared) |
Versioned contract envelope helpers; platform primitives |
@oshun/contracts (libs/contracts) |
Canonical cross-layer contract types and Zod schemas |
Most domain adapters depend on @oshun/domain-registry and @oshun/navigation
in addition to the above. The embodiment adapters depend on their domain client
packages: @oshun/evidence-sophia on @sophia/client, @sophia/schemas, and
@sophia/verification; @oshun/domain-metis on @metis/api-client;
@oshun/embodiment-aja on the @oshun/contracts/aja Zod schemas.
The Oshun shell libraries call domain HTTP APIs through typed adapters; they do
not embed domain implementation logic directly. Platform-wide identity,
data-residency, audit, and observability services are shared infrastructure
under libs/shared/, not part of the Oshun domain.