# ADR-0069: OSHUN Assistant Persona Switching UI Behavior

- Status: Accepted
- Date: 2026-03-26

## Context

OSHUN already had disclosure rules for AI identity, memory state, and synthetic
voice/avatar indicators, plus a continuity rail for assistant handoff. It did
not yet have one shared rule set for how persona switching itself should read
across the assistant shell and Studio governance previews.

That gap created three risks:

- persona identity could be implied by tone or domain badge instead of stated
  explicitly
- persona selection could be confused with disclosure or memory-state visibility
- preview or restricted personas could disappear silently instead of explaining
  why they are gated

The V1 TODO list explicitly requires the visual rules for assistant persona
switching to be defined. Research into current assistant control patterns also
showed a stable expectation: the active mode or guide should remain visible,
alternatives should stay inspectable, and unavailable choices should explain
their gate rather than behaving like broken controls.

## Decision

Publish one canonical assistant-persona-switching behavior contract from
`libs/oshun/design-tokens/src/tokens.ts` and make the web shell consume it
through shared CSS variables, a persona-switching helper, representative
assistant-shell UI, and Studio governance previews.

The shell contract is:

1. Active identity stays visible
   - the current persona remains visible in the assistant header or summary
     surface at all times

2. Continuity is preserved by default
   - persona switching keeps the current thread, disclosure strip, and memory
     scope unless a later policy/runtime layer explicitly requires a break

3. Persona is not disclosure
   - persona choice is a guidance lens and must not replace AI identity,
     memory-state, or synthetic modality indicators

4. Domain affinity guides but does not lock
   - the current domain can elevate a recommended persona, but the broader
     catalog stays visible so the user knows a deliberate switch is happening

5. Gated states need reasons
   - preview and restricted personas must explain why they are limited or
     unavailable in the current surface

## Consequences

- `oshun-v1-foundation` now includes an assistant-persona-switching behavior
  contract alongside the existing domain-accent, grounded-evidence, disclosure,
  trust-signal, and admin-state contracts.
- `apps/oshun/web/src/design-system/globals-v2.css` now defines shared persona
  tones plus switcher-rail, persona-card, compact-chip, active-summary,
  continuity-note, state-badge, and accent-bar variables.
- `apps/oshun/web/src/design-system/assistant-persona-switching.ts` now provides
  the canonical web helper layer for default persona resolution, state mapping,
  and continuity-safe switcher summaries.
- `apps/oshun/web/src/components/assistant/AssistantPanel.tsx` now keeps the
  active persona explicit while rendering recommended, preview, and restricted
  persona options inside the global assistant shell.
- Studio design-language and Isis text-to-speech workspaces now expose the same
  governed persona grammar for review rather than inventing local persona cards.

## Implementation

- Shared contract:
  - `libs/oshun/design-tokens/src/tokens.ts`
  - `libs/oshun/design-tokens/src/tokens.test.ts`
- Web adapter and CSS:
  - `apps/oshun/web/src/design-system/tokens.ts`
  - `apps/oshun/web/src/design-system/index.ts`
  - `apps/oshun/web/src/design-system/assistant-persona-switching.ts`
  - `apps/oshun/web/src/design-system/globals-v2.css`
  - `apps/oshun/web/src/design-system/__tests__/tokens.test.ts`
  - `apps/oshun/web/src/design-system/__tests__/assistant-persona-switching.test.ts`
- Representative assistant and Studio surfaces:
  - `apps/oshun/web/src/components/assistant/AssistantPanel.tsx`
  - `apps/oshun/web/src/components/studio/StudioDesignLanguageWorkspace.tsx`
  - `apps/oshun/web/src/components/studio/StudioIsisTextToSpeechWorkspace.tsx`
- Web and browser verification:
  - `apps/oshun/web/src/components/assistant/__tests__/AssistantPanel.test.tsx`
  - `apps/oshun/web/src/components/__tests__/StudioDesignLanguageWorkspace.test.tsx`
  - `apps/oshun/web/src/components/__tests__/StudioIsisTextToSpeechWorkspace.test.tsx`
  - `apps/oshun/web/src/components/__tests__/StudioIsisTextToSpeechWorkspace.integration.test.tsx`
  - `apps/oshun/web/e2e/assistant-continuity-journey.spec.ts`
  - `apps/oshun/web/e2e/studio-design-language-smoke.spec.ts`
  - `apps/oshun/web/e2e/studio-isis-text-to-speech-smoke.spec.ts`

## Verification

This slice is complete when:

1. shared design-token tests pass
2. targeted web persona-switching, assistant-shell, and Studio tests pass
3. targeted eslint passes for the changed shared and web source files
4. Playwright verifies assistant persona switching plus Studio design-language
   and text-to-speech governance previews
