Files
waggle-os/docs/ux-disclosure-levels.md
Oleg Maslov 0c3e2ead3b
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled
moving
2026-09-02 10:10:29 +02:00

21 KiB
Raw Blame History

UX Disclosure Levels — Source-of-Truth Spec

Status: DRAFT r2 — generated by /plan-design-review 2026-05-07. r1 was the wrong direction (assumed flat sidebar layout). r2 documents the actual live UI: Mac-OS-style desktop with bottom dock + windowed apps. Approval pending. Drives: Phase 4.1 polish-sprint scope (filter onboarding to match existing dock-tier filtering) + Phase 4.2 PersonaSwitcher 2-tier work + downstream design polish work. Reference plan: ~/.gstack/projects/marolinik-waggle-os/markomarkovic-main-design-20260506-175017.md


What this is

Waggle OS is a Mac-OS-style desktop running inside a Tauri 2.0 binary. The UI shell consists of:

  • Desktop (apps/web/src/components/os/Desktop.tsx) — full-bleed canvas
  • Bottom dock (apps/web/src/components/os/Dock.tsx) — Mac-OS-style centered floating glass panel with app icons
  • Status bar (apps/web/src/components/os/StatusBar.tsx) — top thin bar
  • Windowed apps (apps/web/src/components/os/AppWindow.tsx) — apps open as draggable, resizable windows
  • Overlays (apps/web/src/components/os/overlays/) — onboarding, persona switcher, workspace switcher, modals
  • Boot screen (apps/web/src/components/os/BootScreen.tsx) — first-launch animation

The 3-level UX disclosure operates at the dock level: the dock filters which apps are visible based on the user's chosen UserTier (simple / professional / power), with an additional layer that hides specific entries below their minBillingTier (FREE / TRIAL / PRO / TEAMS / ENTERPRISE).

This spec documents that existing system as canonical and identifies gaps to close before pilot.

Naming alignment

Three names referenced different things historically:

Internal enum (UserTier) Display label (TIER_OPTIONS) Brownfield doc name This spec
simple Essential "simple" Essential (simple)
professional Standard "advanced" Standard (professional)
power Everything "pro" Everything (power)

Plus admin (UserTier only) which currently aliases to power's dock config.

Source of truth: apps/web/src/lib/dock-tiers.ts (TIER_DOCK_CONFIG const). Display labels were renamed in QW-5 to avoid collision with billing tiers (Pro $19, Teams $49). Internal enum values stay simple/professional/power for backward compatibility with stored user preferences.

Default

New user starts at Essential. The 8-step onboarding wizard's TierStep (step 3) preselects Essential. Trial users get the same Essential default with reveal moments to Standard. Power is opt-in only via Settings → Display.


Dock contents — already implemented in dock-tiers.ts

This is the EXISTING canonical filtering. Spec's job is to document and audit.

Essential (simple) — 5 dock items (verified)

TIER_DOCK_CONFIG.simple = [
  { key: 'home',    appId: 'dashboard', icon: LayoutDashboard, label: 'Home',     color: 'text-sky-400' },
  { key: 'chat',    appId: 'chat',      icon: MessageSquare,   label: 'Chat',     color: 'text-primary' },
  { key: 'files',   appId: 'files',     icon: FolderOpen,      label: 'Files',    color: 'text-amber-300' },
  { type: 'separator' },
  { key: 'vault',   appId: 'vault',     icon: Lock,            label: 'Vault',    color: 'text-amber-400' },
  { key: 'system',  appId: 'settings',  icon: Settings,        label: 'Settings', color: 'text-muted-foreground' },
]

5 items + 1 separator. Memory is NOT in Essential — it's deliberately gated to Standard+ because the discovery moment for "Waggle remembers everything" is the chat surface (where context-restore + login briefing happens), not a separate Memory app.

Standard (professional) — 7 dock items (verified)

Adds Personas (agents) + Memory between Files and Vault. Same 5 from Essential plus:

{ key: 'agents', appId: 'agents', icon: Bot,   label: 'Personas', color: 'text-orange-400' },  // after chat
{ key: 'memory', appId: 'memory', icon: Brain, label: 'Memory',   color: 'text-amber-300' },   // after separator

Everything (power) — full configuration

Power dock adds Room, Waggle Dance, two zone-parents (Ops + Extend) with collapsible trays, plus Approvals (TEAMS-only) above Vault.

  • Ops zone-parent (tray): Command Center, Timeline, Usage & Cost, Events & Logs, Scheduled Jobs
  • Extend zone-parent (tray): Skills & Apps, Connectors, Team Governance (TEAMS-only)
  • Plus Approvals (TEAMS-only)

Marketplace is a TAB inside Skills & Apps (per P31 comment), not a separate dock item — the spec leaves it that way.

Billing tier filtering layer

Per-entry minBillingTier runs ON TOP of UserTier filtering. Examples already in code:

  • governance requires TEAMS
  • approvals requires TEAMS

Phase 4.1 may need to add minBillingTier: 'PRO' to dock entries for Pro-only features (skills marketplace? custom personas? — TBD per Open Q1 below).


Onboarding wizard — 8 steps already exist (audit)

Files: apps/web/src/components/os/overlays/onboarding/{Welcome, WhyWaggle, Tier, Import, Template, Persona, ApiKey, Ready}Step.tsx

# Step Current behavior Phase 4.1 audit
1 welcome Hero card + brand + CTA OK
2 why-waggle 3 value props: Remembers everything / Workspace-native / Real tools OK
3 tier Pick Essential / Standard / Everything (Essential preselected) OK — uses TIER_OPTIONS
4 memory-import ChatGPT/Claude/Gemini/Perplexity/Cursor/Claude Code import + auto-detect OK
5 template Currently shows ALL 15 templates GAP — should filter by tier
6 persona Currently shows ALL 19 onboarding personas via getPersonasForTemplate() GAP — should filter by tier
7 api-key Provider + key + vault auto-detect OK; add Ollama default in Phase 4.1 (Open Q from brownfield doc)
8 ready Summary + first-task + open workspace OK

The Phase 4.1 unblock is consistency: dock filters to 5 items at Essential, but onboarding template + persona steps show ALL options regardless of tier. That's an internal inconsistency the user feels — they pick Essential at step 3, then step 5 throws 15 templates at them.

Templates — filter for Essential — 3 of 15

When selectedTier === 'simple', TemplateStep.tsx should default to showing 3 templates with a "Show all 15 templates" toggle:

ID Display Why at Essential Recommended persona
agency-consulting Consulting Marko's archetype, Ljiljana's role, broadest professional services match consultant
research-project Research Hub Universally useful (HR research, market research, due diligence) researcher
blank Blank Workspace Universal escape — any user who doesn't fit a category general-purpose

The other 12 templates remain available via "Show all" toggle (no hard gating — users at Essential who want their domain template aren't blocked). Standard and Everything see all 15 by default.

Personas — filter for Essential — 4 of 22 (matches tier field already in code)

ALL_ONBOARDING_PERSONAS already declares 3 cohorts via the tier field:

  • tier='universal' (1): general-purpose
  • tier='knowledge' (4): researcher, writer, analyst, coder
  • tier='domain' (14): project-manager, executive-assistant, sales-rep, marketer, product-manager-senior, hr-manager, legal-professional, finance-owner, consultant, support-agent, ops-manager, data-engineer, recruiter, creative-director

When selectedTier === 'simple', PersonaStep.tsx should show universal + knowledge cohorts (5 personas: general-purpose, researcher, writer, analyst, coder) PLUS the recommended persona for the selected template (e.g. consultant if Consulting selected). getPersonasForTemplate() already does the recommended-first ordering — no logic change needed, just filter to universal+knowledge tiers when selectedTier === 'simple'.

Decision needed (Open Q): coder at Essential — keep or drop? Coder is in tier='knowledge' cohort. Marko's quote: "this is not the target, unless you identify this tool can be useful for coders too, which I don't believe." Recommend dropping coder from Essential default (drop the tier='knowledge' filter to "knowledge minus coder" or rename coder to tier='domain'). Result: 4 personas at Essential (general-purpose, researcher, writer, analyst) + recommended-from-template.

The other 14 domain personas + 3 hidden meta-personas (planner, verifier, coordinator) stay accessible at Standard+.

planner, verifier, coordinator remain hidden from ALL_ONBOARDING_PERSONAS entirely (they're orchestration meta-personas, not user-facing).


Settings app — filter sections per tier

Current state: SettingsApp.tsx shows all sections regardless of UserTier. Phase 4.1 adds level filtering.

Settings at Essential

Section Shown
Profile
Models (provider, API key, Ollama on/off)
Display (theme, level toggle)
Memory (view-only stats, opt-out delete path)
Billing/Subscription if user is Trial/Pro/Teams

Hidden at Essential (visible at Standard+): Tools, Skills, Connectors, Personas (manage), MCP servers, Telemetry, Compliance (Everything+), Evolution (Everything+), Vault management (auto-managed at Essential), Team (TEAMS-only).

Display panel — the level toggle

Level toggle UI: 3-card chooser using existing TIER_OPTIONS array. Currently lives in TierStep.tsx for onboarding; Phase 4.1 adds the same chooser to Settings → Display so users can switch level post-onboarding.


Skills + connectors at Essential — personalize, don't cap

Reframe (2026-05-08, Marko): the previous version of this section proposed pre-installing only 5 skills + 3 connectors at Essential. That framing is wrong. Hiding 13 of 18 skills doesn't simplify — the agent already loads all 18 invisibly so the capability ceiling is unchanged either way; the user just feels it has less. Hiding 145 of 148 connectors doesn't simplify — connectors are zero-installed by default and only activate on user OAuth, so the configuration burden is identical either way; the user just can't find Linear or GitHub when they have those accounts. Capability is never the simplification target. Discoverability + first-screen relevance is.

Skills (built-in) — all 18 stay loaded

The starter pack at packages/sdk/src/starter-skills/ ships 18 skills that are auto-installed on first run by packages/server/src/local/routes/skills.ts:54-63. They are loaded into the agent regardless of tier. No tier-based gating on the loaded set.

What CAN vary by tier:

  • Display surface of the skills picker UI (Settings → Skills tab, marketplace tab visibility) — currently TIER_DOCK_CONFIG already gates the marketplace dock entry.
  • In-chat skill suggestions ("Try draft-memo for that?") can be persona-aware so a Coder gets code-review and a Consultant gets research-synthesis without scrolling. Implementation: future Phase 4c — chat skill hint surface.

Connectors (MCP catalog) — all 148 reachable, recommendation per persona

The MCP catalog at packages/shared/src/mcp-catalog.ts has 148 connectors across 14 categories. Default install state: zero. Every connector requires user OAuth.

What changes by persona (not by tier): the connector landing surface inside ConnectorsApp + the optional onboarding "which tools?" step recommend a primary set of 35 connectors based on the user's chosen template + persona. Source of truth: packages/shared/src/connector-recommendations.ts + the recommendConnectors() helper. The full 148 stay browseable and searchable at every tier.

Examples (full table in connector-recommendations.ts):

Persona Primary recommendation
consultant notion-mcp, gdrive-mcp, gmail-mcp, slack-mcp, figma
coder github-mcp, slack-mcp, linear-mcp, sentry, gdrive-mcp
sales-rep hubspot-mcp, salesforce-mcp, slack-mcp, gmail-mcp, notion-mcp
analyst bigquery, postgres, gdrive-mcp, notion-mcp, excel
general-purpose / planner / verifier / coordinator gdrive-mcp, gmail-mcp, notion-mcp (universal defaults)

Validation: every recommended ID is asserted to exist in the catalog by packages/shared/tests/connector-recommendations.test.ts. A typo'd or removed connector ID is caught at CI before it ships an empty tile.

Net effect on the user

  • A consultant who picked Essential during onboarding still has all 148 connectors reachable via ConnectorsApp → All. The first thing they SEE is just notion / gdrive / gmail / slack / figma — the five most likely to matter for that role.
  • The same consultant on Standard or Everything sees the same 5 first; the only difference between tiers is which dock items are visible (chat / files / home / vault / settings + memory + agents at Standard + ops console + marketplace at Everything). Connector capability is identical across tiers.

Empty / loading / error / partial states for Essential surfaces

For each of the 5 dock-visible apps at Essential, specify what user sees in non-happy states.

Home (Dashboard) — Day 1, just after onboarding

  • Empty: Grid layout with: workspace name + persona name top-left, "What's on your mind?" with chat input placeholder, 3 starter-prompt chips drawn from TEMPLATES[selected].hint + persona's bestFor[0] example, "Waggle is learning your work" memory hint card. NOT "No items found."
  • Returning user: WorkspaceBriefing card shows context recap from last session ("Last session: drafted HR policy v3, saved 8 frames").
  • Loading: subtle skeleton (matches existing chat shimmer pattern from M2-7).
  • Error (memory unavailable): "Memory layer is initializing. You can start chatting; Waggle will remember once memory is ready." + retry button. NEVER show stack trace at Essential.

Chat (in-window app)

  • Empty (new conversation): persona-aware welcome line (e.g. for consultant: "Hi — I'm here for your client work. What are we tackling?") + 3 quick-start chips from persona's bestFor.
  • Loading (LLM call in flight): existing shimmer pattern.
  • Error (API key invalid): "Looks like the API key needs attention. [Open Settings]" — NOT a 500 stack.
  • Error (LLM rate limit / 429): "The model is busy. Trying again in 5s..." with retry counter.
  • Error (network down): "Lost connection. Your message is saved; will retry when back online." + offline indicator.

Files

  • Empty: "Drop files here, or browse from your computer." Drag-drop hint + button. (FileUploadZone component already exists.)
  • Loading: skeleton rows.
  • Error (storage quota): "You're using X of Y. Free tier supports Z files. [Upgrade]" — visible only when tier is Free + close to quota.

Vault (Essential)

  • Empty: "Your API keys live here, encrypted on your device." + "Add a key" button.
  • Editing: keys masked by default; reveal-on-click with confirmation.

Settings

  • API key invalid: inline error on the field, not a modal. "Key looks invalid — try again." + provider docs link.
  • Memory purge confirmation: double-confirm dialog with "Type DELETE to confirm" pattern (untechnical-but-decisive UX, prevents accidents). Required for pilot data handling per brownfield doc.
  • Level switch (Essential → Standard): confirmation + "You'll see more apps in your dock. Switch back anytime in Settings → Display."

Responsive + a11y posture

Day 0 stance: Desktop-only (Win + Mac). Tauri binary. NO mobile/tablet responsive promises in launch comms. Dock has horizontal scroll fallback at <768px viewports (already implemented per L-01/R-1 comment in Dock.tsx:72).

A11y at Essential — non-negotiable (most already implemented):

  • Existing Esc-to-skip in OnboardingWizard (verified at line 81) — keep
  • Existing dock label visibility for new users (useDockLabels <20 sessions or <7 days) — keep
  • Tab order: status bar → dock → desktop → workspace context
  • Focus visible on every interactive element (waggle-theme.css ring tokens)
  • 4.5:1 contrast minimum on body text — light mode currently broken (P0 from brownfield doc), must fix in Phase 4.1
  • Touch targets: 44px min
  • Screen reader landmarks: <main> (Desktop), role="toolbar" (Dock), aria-label per dock entry
  • Memory + workspace state announce on switch (aria-live="polite")

Reveal moments — how a user discovers Standard / Everything

Three reveal triggers (least intrusive first):

  1. Tooltip on first attempt to access a hidden feature. E.g. user tries to spawn a multi-agent group from Chat — sees "Multi-agent groups need Standard. [Try Standard]". Standard switch is one-click + reversible.
  2. Settings → Display level toggle with TIER_OPTIONS chooser — same UI as TierStep in onboarding.
  3. Soft nudge after 7 days of consistent use: "You've been using Waggle daily. Standard adds Personas + Memory + agent workflows. Try it for 7 days." Dismissible. Once-per-user-lifetime.

Power level is opt-in only — never nudged. User must navigate Settings → Display → Everything explicitly.


What this spec does NOT cover (out of scope)

  • Visual mockups of dock + windowed apps — the live UI is the visual reference; downstream /design-review runs on the live binary.
  • Pixel-level component design — handled by /design-consultation (recommend running before Phase 4.1 implementation).
  • Marketing-page (apps/www) design — separate spec.
  • Tier billing UX (free vs Pro vs Teams) — handled by upgrade modal redesign (Phase 4.1 must-have, separate from level disclosure).
  • New apps — this spec only covers filtering existing apps; the 26 existing apps are out of scope for "what to add."

Acceptance criteria

This spec is approved when:

  1. Marko reviews and signs off on the named selections (3 templates / 4 personas at Essential) and the Open Q answers.
  2. Phase 4.1 implementer has enough specificity to implement: (a) filter TEMPLATES in TemplateStep.tsx when tier === 'simple', (b) filter ALL_ONBOARDING_PERSONAS by tier field when tier === 'simple', (c) filter SettingsApp.tsx sections per tier, (d) write empty/loading/error copy for the 5 Essential surfaces.
  3. Open Questions 1-3 resolved.

Open Questions

  1. Coder at Essential — keep or drop? Recommend drop; Marko's quote supports it.
  2. Pre-installed skills exact selection. 5 listed; confirm or swap. CLOSED 2026-05-08 — superseded by reframe: all 18 starter skills stay loaded, no tier-based gating. See "Skills + connectors at Essential — personalize, don't cap" above.
  3. Pre-installed connectors selection. 3 listed; confirm Gmail vs M365 default vs choose-during-onboarding. CLOSED 2026-05-08 — superseded by connector-recommendations.ts (persona-aware primary set, full 148 stay reachable). Gmail vs M365 picker still belongs in onboarding "which tools?" step (Phase 4b).
  4. minBillingTier on dock entries — does Pro need any? E.g. should marketplace marketplace have minBillingTier: 'PRO'? Defer to Stripe-products work in Phase 4.1.
  5. Reveal nudge timing — 7 days or session-count-based? Recommend 7 days based on useDockLabels precedent.

References (live code, not memory)

  • Dock + tier config: apps/web/src/lib/dock-tiers.ts (TIER_DOCK_CONFIG, getDockForTier, BILLING_TIER_ORDER, filterByBillingTier)
  • Dock component: apps/web/src/components/os/Dock.tsx (renders getDockForTier(tier, billingTier), includes zone-parent tray pattern + horizontal scroll fallback)
  • Tier display labels: apps/web/src/components/os/overlays/onboarding/constants.ts (TIER_OPTIONS)
  • Onboarding constants: same file (TEMPLATES, ALL_ONBOARDING_PERSONAS, TEMPLATE_PERSONA, VALUE_PROPS, getPersonasForTemplate)
  • Persona canon: packages/agent/src/persona-data.ts (22 personas total; 19 in onboarding picker; 3 meta-personas hidden)
  • Onboarding shell: apps/web/src/components/os/overlays/OnboardingWizard.tsx (8-step shell with STEP_NAMES constant)
  • Theme: apps/web/src/waggle-theme.css (Hive DS tokens)
  • Voice: docs/BRAND-VOICE.md
  • Architecture: docs/ARCHITECTURE.md

Revision log

  • r1 (2026-05-07 14:09) — initial draft, wrong direction (assumed flat sidebar). Mockups also generated in wrong direction; discarded.
  • r2 (2026-05-07 14:30) — corrected per Marko: documented the actual live Mac-OS-style dock + windowed apps + existing TIER_DOCK_CONFIG. Spec now AUDITS existing code instead of redesigning. 5 dock items at Essential matched against TIER_DOCK_CONFIG.simple (correct). Memory pulled from Essential to Standard+ (matches code). Added zone-parent + minBillingTier handling. Onboarding gap identified: template+persona steps don't filter by tier.
  • r3 (2026-05-08) — reframed "Pre-installed skills/tools/connectors at Essential" section per Marko's pushback: capping skills/connectors at Essential reduces capability without simplifying anything (skills are auto-loaded regardless; connectors are zero-installed by default). Replaced with personalize-don't-cap framing: all 18 skills stay loaded, all 148 connectors stay reachable, persona-aware primary recommendation surface drives the connector landing tile. Source of truth: packages/shared/src/connector-recommendations.ts (22-persona map + universal fallback, validated against mcp-catalog.ts membership in tests). Closed Q2 + Q3 against this approach. Phase 4b will wire ConnectorsApp landing + onboarding "which tools?" step; Phase 4c will add chat skill hints.