kalei/docs/technical/kalei-user-journey-technica...

38 KiB

Kalei — User Journey Technical Map

Version 1.0 — February 2026 Maps every user-facing flow to backend API endpoints, database operations, frontend components, and AI calls


Architecture Summary

Backend: Fastify 5.x (Node.js 22 LTS), Drizzle ORM, PostgreSQL 16, Redis 7 Frontend: React Native + Expo SDK 54+, Expo Router, TanStack Query v5, Zustand, MMKV v4 AI: DeepSeek V3.2 via OpenRouter (primary, hosted on DeepInfra/Fireworks US/EU), Claude Haiku 4.5 (automatic fallback), provider-agnostic AI Gateway Auth: JWT with refresh token rotation, Apple/Google SSO Billing: Direct App Store / Google Play webhook integration


1. Authentication & Onboarding

1.1 Account Registration

User Action: Enters email + password or taps Apple/Google SSO

Layer Detail
API POST /auth/register — body: { email, password, provider? }
Validation Zod: email format, password 8+ chars, provider enum
DB Write INSERT INTO users (id, email, password_hash, created_at)
DB Write INSERT INTO profiles (user_id, display_name, coaching_style, onboarding_complete)
DB Write INSERT INTO subscriptions (user_id, plan, status, started_at) — defaults to free
Redis Set rate:auth:{ip} with TTL for brute-force protection
Response { access_token, refresh_token, user: { id, email, profile } }
Frontend AuthStore.setTokens() → MMKV encrypted storage → navigate to onboarding

1.2 Token Refresh

Layer Detail
API POST /auth/refresh — body: { refresh_token }
DB Read SELECT FROM refresh_tokens WHERE token = $1 AND revoked = false
DB Write Revoke old token, issue new pair (rotation)
Redis Invalidate old session cache

1.3 Onboarding Completion

User Action: Completes screens 2-9 (style selection, first Turn)

Layer Detail
API PATCH /me/profile — body: { coaching_style, notification_time, onboarding_complete: true }
DB Write UPDATE profiles SET coaching_style = $1, notification_time = $2, onboarding_complete = true
Push Schedule first notification via push service at chosen time
Frontend OnboardingStore.complete() → navigate to main tab navigator

2. The Turn (Reframing)

2.1 Submit a Turn

User Action: Types thought → taps "Turn it"

Layer Detail
Frontend Validate non-empty input, show Turn animation (1.5s kaleidoscope rotation)
API POST /turns — body: { input_text, coaching_style? }
Rate Check Redis: INCR rate:turns:{user_id}:{date} → reject if > 3 (free) or > 100 (prism)
Entitlement SELECT plan FROM subscriptions WHERE user_id = $1 → gate check
Safety Deterministic keyword scan → if flagged: INSERT INTO safety_events, return crisis response
AI Call AI Gateway → Claude Haiku 4.5: system prompt (coaching style + reframe instructions) + user input
AI Response JSON: { perspectives: [{ style, text, emotion_before, emotion_after }], micro_action: { if_clause, then_clause }, fragments_detected: [{ type, phrase, confidence }] }
DB Write INSERT INTO turns (id, user_id, input_text, perspectives, micro_action, fragments, emotion_vector, created_at)
DB Write INSERT INTO ai_usage_events (user_id, feature, model, input_tokens, output_tokens, latency_ms, cost_usd)
Redis Increment daily counter, update streak cache
Response { turn_id, perspectives, micro_action, fragments, pattern_seed }
Frontend Dismiss animation → render 3 perspective cards + micro-action card

2.2 Save a Turn / Keepsake

User Action: Taps save on a perspective card

Layer Detail
API POST /turns/{id}/save — body: { perspective_index, save_type: "keepsake" }
DB Write UPDATE turns SET saved = true, saved_perspective_index = $1
DB Write INSERT INTO evidence_wall_tiles (user_id, tile_type, source_feature, source_id, color_accent, created_at) — type: saved_keepsake
Response { saved: true, gallery_id, evidence_tile_id }
Frontend Success toast "Turn saved" → update Gallery cache via TanStack Query invalidation

2.3 Get Turn History

Layer Detail
API GET /turns?limit=20&offset=0&date=2026-02-21
DB Read SELECT id, input_text, perspectives, fragments, created_at FROM turns WHERE user_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3
Cache Redis: cache recent 20 turns per user, 5 min TTL

3. The Mirror (Journaling + Fragment Detection)

3.1 Start Mirror Session

User Action: Opens Mirror tab → starts new session

Layer Detail
API POST /mirror/sessions — body: { prompt_id? }
Rate Check Redis: INCR rate:mirror:{user_id}:{week} → reject if > 2 (free)
DB Write INSERT INTO mirror_sessions (id, user_id, status, started_at) — status: active
Response { session_id, opening_prompt }
Frontend Navigate to session view, show opening prompt in AI bubble

3.2 Send Message in Mirror

User Action: Types and sends a message

Layer Detail
Frontend Append user message to local state, show AI thinking animation
API POST /mirror/sessions/{id}/messages — body: { content, message_type: "user" }
DB Write INSERT INTO mirror_messages (id, session_id, role, content, created_at)
AI Call #1 Fragment Detection: system prompt (10 distortion types + detection rules) + session context + new message
AI Response #1 { fragments: [{ type, phrase, start_index, end_index, confidence }] }
Entitlement Gate Free: filter to 3 types (catastrophizing, black_and_white, should_statements). Prism: all 10
DB Write INSERT INTO mirror_fragments (id, session_id, message_id, distortion_type, phrase, start_idx, end_idx, confidence)
AI Call #2 Reflective Response: system prompt (warm, non-directive, Mirror voice) + session history + detected fragments
AI Response #2 { response_text, suggested_prompts: [] }
DB Write INSERT INTO mirror_messages (id, session_id, role: "assistant", content)
Response { message_id, ai_response, fragments: [{ type, phrase, indices }] }
Frontend Render AI response bubble, apply amber highlight underlines to user's message at fragment positions

3.3 Tap Fragment Highlight → Inline Reframe

User Action: Taps highlighted text in their message

Layer Detail
Frontend Open half-sheet modal with distortion info (local data from fragment detection response)
API POST /mirror/fragments/{id}/reframe — body: { fragment_id }
Rate Check Free: 1 inline reframe per session
AI Call Quick reframe: system prompt + fragment context + distortion type
AI Response { reframes: [{ text, style }], can_turn: true }
Response { reframes, turn_prefill }turn_prefill is the fragment phrase ready for Turn
Frontend Render reframes in half-sheet. "Take to Turn" button navigates to Turn tab with input_text pre-filled

3.4 Close Mirror Session → Generate Reflection

User Action: Taps "End Session" or navigates away

Layer Detail
API POST /mirror/sessions/{id}/close
DB Read Fetch all messages + fragments for session
AI Call Reflection generation: full session transcript + all fragments → themes, insight, pattern seed
AI Response { themes: [], fragment_summary: { total, by_type }, insight: "string", pattern_seed: "hash" }
DB Write UPDATE mirror_sessions SET status = "closed", reflection = $1, pattern_seed = $2, closed_at = NOW()
DB Write INSERT INTO evidence_wall_tiles (user_id, tile_type: "mirror_reflection", source_id, ...)
Response { reflection, pattern_seed, fragment_summary }
Frontend Show reflection card with generated kaleidoscope pattern thumbnail → auto-saved to Gallery

4. The Lens (Goals + Actions)

4.1 Create Goal

Layer Detail
API POST /lens/goals — body: { title, description, target_date?, category? }
AI Call Goal refinement: make SMART, suggest metrics, generate initial visualization description
DB Write INSERT INTO lens_goals (id, user_id, title, description, target_date, visualization_text, status, created_at)
Response { goal_id, refined_title, visualization, suggested_actions }

4.2 Get Daily Actions + Affirmation

Layer Detail
API GET /lens/today
DB Read Active goals + incomplete actions + today's affirmation
AI Call (if no affirmation cached) Generate daily affirmation based on active goals + recent progress
Redis Cache today's affirmation, 24h TTL
Response { goals: [...], today_actions: [...], affirmation: { text, goal_id } }

4.3 Complete Action

Layer Detail
API POST /lens/actions/{id}/complete
DB Write UPDATE lens_actions SET completed = true, completed_at = NOW()
DB Write INSERT INTO evidence_wall_tiles (tile_type: "completed_action", source_id, color_accent: "emerald")
Redis Update streak counter
Response { completed: true, goal_progress_pct, streak_count, evidence_tile_id }

4.4 Start Rehearsal Session

User Action: On goal detail → taps "Rehearse"

Layer Detail
API POST /lens/goals/{id}/rehearsal
Rate Check Free: 1/week, Prism: unlimited
DB Read Fetch goal details + user's recent Mirror/Turn data for personalization
AI Call Visualization script generation: first-person, multi-sensory, process-oriented, obstacle rehearsal
AI Response { script_segments: [{ text, duration_seconds, breathing_cue? }], total_duration }
DB Write INSERT INTO rehearsal_sessions (id, user_id, goal_id, script, duration, created_at)
Response { session_id, script_segments, total_duration }
Frontend Enter Rehearsal mode: timer ring, text card sequence with breathing animation pacing

4.5 Complete Rehearsal

Layer Detail
API POST /lens/rehearsals/{id}/complete
DB Write UPDATE rehearsal_sessions SET completed = true, completed_at = NOW()
DB Write INSERT INTO evidence_wall_tiles (tile_type: "rehearsal_complete", source_id, color_accent: "amethyst")
Response { completed: true, evidence_tile_id }
Frontend Success burst animation → navigate back to goal detail

5. The Ritual (Daily Habit Sequences)

5.1 Start Ritual

User Action: Taps "Start Ritual" on Turn tab or from notification

Layer Detail
API POST /rituals/start — body: `{ template: "morning"
Rate Check Free: only quick template allowed
DB Write INSERT INTO ritual_sessions (id, user_id, template, status, started_at)
DB Read Fetch user's active goals, recent fragments, streak data for personalization
AI Call Personalize ritual prompts based on user context
Response { session_id, steps: [{ type, prompt, duration_seconds }] }
Frontend Enter Ritual mode: fragment-shaped step progress bar, step-by-step flow

5.2 Ritual Step Completion

Each step may trigger its own API call:

Step API Calls
Mirror check-in POST /mirror/sessions + POST /mirror/sessions/{id}/messages (lightweight, 1-2 exchanges)
Turn POST /turns (with ritual context flag)
Lens review POST /lens/actions/{id}/complete (for each completed action)
Affirmation GET /lens/today (cached)
Gratitude POST /rituals/{id}/gratitude — body: { text }

5.3 Complete Ritual

Layer Detail
API POST /rituals/{id}/complete
DB Write UPDATE ritual_sessions SET status = "completed", completed_at = NOW()
DB Write INSERT INTO evidence_wall_tiles (tile_type: "ritual_complete", color_accent: "amber")
Redis Update ritual streak: INCR streak:ritual:{user_id}, check context consistency (same time ± 30 min)
DB Write UPDATE profiles SET ritual_streak = $1, ritual_consistency_score = $2
Response { completed: true, streak_count, consistency_score, evidence_tile_id }
Frontend Prismatic ring completion animation → streak view

6.1 Get All Patterns

Layer Detail
API GET /gallery?view=all&limit=20&offset=0
DB Read SELECT id, source_feature, pattern_seed, preview_text, created_at FROM gallery_items WHERE user_id = $1 ORDER BY created_at DESC
Cache Redis: cache first page, 2 min TTL

6.2 Get Pattern Detail

Layer Detail
API GET /gallery/{id}
DB Read Full gallery item with source content, fragments, pattern seed
Frontend Render hero kaleidoscope pattern (deterministic from seed), source content, metadata

6.3 Search / Filter

Layer Detail
API GET /gallery/search?q=text&feature=turn&distortion=catastrophizing&from=2026-01-01
DB Read Full-text search on gallery content + filter joins

6.4 Generate Pattern Card (Share)

Layer Detail
API POST /gallery/{id}/share
Backend Generate Pattern Card image: kaleidoscope pattern + reframe text overlay + Kalei watermark
Response { share_url, image_url }
Frontend Native share sheet with generated image

7. Evidence Wall

7.1 Get Evidence Wall

Layer Detail
API GET /evidence-wall?limit=50
DB Read SELECT * FROM evidence_wall_tiles WHERE user_id = $1 ORDER BY created_at DESC
Entitlement Free: 30-day window (WHERE created_at > NOW() - INTERVAL '30 days'). Prism: all history
Response `{ tiles: [...], connections: [...], stage: "empty"
Frontend Render mosaic view based on stage, assign tile shapes (diamond, hex, rect, pentagon, triangle) based on tile_type

7.2 Get Tile Detail

Layer Detail
API GET /evidence-wall/tiles/{id}
DB Read Tile + source data (join to turns/mirror_sessions/lens_actions/ritual_sessions/rehearsal_sessions)
Response { tile, source_content, source_feature, created_at }
Frontend Half-sheet with tile detail, source content, link to source feature

7.3 Contextual Evidence Surfacing

Trigger: AI detects low self-efficacy language in Mirror or Turn

Layer Detail
AI Detection During Mirror fragment detection or Turn processing, flag self-efficacy score < threshold
DB Read SELECT * FROM evidence_wall_tiles WHERE user_id = $1 ORDER BY relevance_score DESC LIMIT 2
Response Included in Mirror/Turn response: { evidence_nudge: { tiles: [...], message: "..." } }
Frontend Render gentle card below main content with 1-2 evidence tiles

8. Spectrum

8.1 Weekly Aggregation (Background Job)

Layer Detail
Trigger Cron: Sunday 6pm UTC
DB Read All turns + mirror_sessions + lens_actions for user's week
AI Call Batch API (50% cost): analyze emotional vectors, fragment patterns, Turn impact
DB Write INSERT INTO spectrum_weekly (user_id, week_start, river_data, glass_data, impact_data, rhythm_data, growth_score, insight_text)
Push Notification: "Your weekly Spectrum insight is ready"

8.2 Get Spectrum Dashboard

Layer Detail
API GET /spectrum/dashboard
Entitlement Free: simplified { weekly_insight_text, basic_fragment_count }. Prism: full dashboard
DB Read Latest weekly + monthly aggregates
Response { river, glass, impact, rhythm, growth, weekly_insight, monthly_insight? }
Frontend Render 5 visualization components from spectrum-visualizations.svg data

8.3 Monthly Deep Dive (Background Job)

Layer Detail
Trigger Cron: 1st of month
DB Read All weekly aggregates for the month
AI Call Batch API: month-over-month narrative generation
DB Write INSERT INTO spectrum_monthly (user_id, month_start, narrative, growth_trajectory, milestone_events)

9. Billing & Entitlements

9.1 Entitlement Check (Middleware)

Every rate-limited endpoint runs this check:

1. Redis: GET entitlement:{user_id} → if cached, return
2. DB: SELECT plan, status FROM subscriptions WHERE user_id = $1 AND status = 'active'
3. Redis: SET entitlement:{user_id} = plan, EX 300 (5 min cache)
4. Return plan → middleware applies feature gates

9.2 App Store Webhook

Layer Detail
API POST /billing/webhooks/apple
Validation Verify Apple JWT signature
DB Write INSERT/UPDATE subscriptions SET plan = $1, status = $2, apple_transaction_id = $3
Redis Invalidate entitlement:{user_id} cache
DB Write INSERT INTO entitlement_snapshots (user_id, plan, event_type, timestamp)

9.3 Google Play Webhook

Same pattern as Apple, with Google-specific JWT validation and google_purchase_token.


10. Safety System

10.1 Crisis Detection Pipeline

Every AI-processed input runs through:

Stage 1: Deterministic keyword scan (regex, ~1ms)
  → If match: flag, skip AI, return crisis template

Stage 2: AI confirmation (during normal processing)
  → AI output includes safety_flag: boolean
  → If flagged: return hardcoded crisis response (never AI-generated)

Stage 3: Logging
  → INSERT INTO safety_events (user_id, input_hash, detection_stage, action_taken)
  → Alert: send to safety dashboard

10.2 Crisis Response

Layer Detail
Response Hardcoded template: empathetic acknowledgment + 988 Suicide & Crisis Lifeline + Crisis Text Line
UI Full-screen modal with prominent crisis resource links, "I'm OK" dismiss button
Logging All crisis events logged, never the content itself

Database Schema Summary

Core Tables

Table Key Columns Indexes
users id (uuid), email, password_hash, created_at email (unique)
profiles user_id (FK), display_name, coaching_style, notification_time, onboarding_complete, ritual_streak, ritual_consistency_score user_id (unique)
subscriptions user_id (FK), plan (enum), status, started_at, expires_at, apple_transaction_id?, google_purchase_token? user_id, status
refresh_tokens id, user_id (FK), token_hash, revoked, expires_at token_hash, user_id

Feature Tables

Table Key Columns Indexes
turns id, user_id, input_text (encrypted), perspectives (jsonb), micro_action (jsonb), fragments (jsonb), emotion_vector (jsonb), saved, pattern_seed, created_at user_id + created_at
mirror_sessions id, user_id, status, reflection (jsonb), pattern_seed, started_at, closed_at user_id + status
mirror_messages id, session_id (FK), role, content (encrypted), created_at session_id + created_at
mirror_fragments id, session_id (FK), message_id (FK), distortion_type (enum), phrase, start_idx, end_idx, confidence session_id, distortion_type
lens_goals id, user_id, title, description, target_date, visualization_text, status, created_at user_id + status
lens_actions id, goal_id (FK), text, if_clause, then_clause, completed, completed_at goal_id + completed
rehearsal_sessions id, user_id, goal_id (FK), script (jsonb), duration, completed, started_at, completed_at user_id + goal_id
ritual_sessions id, user_id, template (enum), status, steps_completed (jsonb), started_at, completed_at user_id + created_at
gallery_items id, user_id, source_feature (enum), source_id, content_preview, pattern_seed, distortion_types (text[]), created_at user_id + source_feature, full-text on content_preview
evidence_wall_tiles id, user_id, tile_type (enum), source_feature, source_id, color_accent, metadata (jsonb), created_at user_id + created_at, user_id + tile_type

Analytics Tables

Table Key Columns Indexes
spectrum_weekly id, user_id, week_start, river_data (jsonb), glass_data (jsonb), impact_data (jsonb), rhythm_data (jsonb), growth_score, insight_text user_id + week_start
spectrum_monthly id, user_id, month_start, narrative (text), growth_trajectory (jsonb), milestone_events (jsonb) user_id + month_start
ai_usage_events id, user_id, feature, model, input_tokens, output_tokens, latency_ms, cost_usd, created_at user_id + feature, created_at
safety_events id, user_id, input_hash, detection_stage, action_taken, created_at user_id, created_at

Enum Types

CREATE TYPE plan_type AS ENUM ('free', 'prism');
CREATE TYPE subscription_status AS ENUM ('active', 'expired', 'canceled', 'trial', 'grace_period');
CREATE TYPE distortion_type AS ENUM ('catastrophizing', 'black_and_white', 'mind_reading', 'fortune_telling', 'personalization', 'discounting_positives', 'emotional_reasoning', 'should_statements', 'labeling', 'overgeneralization');
CREATE TYPE tile_type AS ENUM ('saved_keepsake', 'mirror_reflection', 'completed_action', 'self_correction', 'streak_milestone', 'goal_completion', 'reframe_echo', 'rehearsal_complete', 'ritual_complete');
CREATE TYPE ritual_template AS ENUM ('morning', 'evening', 'quick');
CREATE TYPE source_feature AS ENUM ('turn', 'mirror', 'lens', 'rehearsal', 'ritual');

Redis Key Patterns

Key Type TTL Purpose
rate:turns:{user_id}:{date} counter 24h Daily Turn rate limit
rate:mirror:{user_id}:{week} counter 7d Weekly Mirror rate limit
rate:rehearsal:{user_id}:{week} counter 7d Weekly Rehearsal rate limit
entitlement:{user_id} string 5 min Cached subscription plan
streak:daily:{user_id} hash Current daily streak count + last active date
streak:ritual:{user_id} hash Ritual streak + consistency data
affirmation:{user_id}:{date} string 24h Today's cached affirmation
turns:recent:{user_id} list 5 min Cached recent turns
session:{session_id} hash 2h Active Mirror session context

AI Gateway Call Patterns

Cost Tiers

Feature Model Est. Cost/Call Caching
Turn (reframe) Claude Haiku 4.5 ~$0.003 System prompt cached (40% saving)
Mirror (fragment detection) Claude Haiku 4.5 ~$0.002 System prompt cached
Mirror (reflective response) Claude Haiku 4.5 ~$0.003 System prompt cached
Mirror (session reflection) Claude Haiku 4.5 ~$0.005
Lens (goal refinement) Claude Haiku 4.5 ~$0.004
Rehearsal (script gen) Claude Haiku 4.5 ~$0.008
Ritual (personalization) Claude Haiku 4.5 ~$0.003 System prompt cached
Spectrum (weekly) Claude Batch API ~$0.010 Batch (50% off)
Spectrum (monthly) Claude Batch API ~$0.015 Batch (50% off)
Safety (confirmation) Included in feature call $0 Part of existing call

Prompt Template Versioning

All prompts stored as versioned templates: prompts/{feature}/{version}.json

Prompt Current Version
turn_reframe v1.0
mirror_fragment_detect v1.0
mirror_reflect v1.0
mirror_session_close v1.0
lens_goal_refine v1.0
rehearsal_script v1.0
ritual_personalize v1.0
spectrum_weekly v1.0
spectrum_monthly v1.0
safety_check v1.0

Frontend Component Architecture

Navigation

AppNavigator (Expo Router)
├── (auth)
│   ├── login.tsx
│   ├── register.tsx
│   └── onboarding/
│       ├── welcome.tsx
│       ├── metaphor.tsx
│       ├── turn-demo.tsx
│       ├── style-select.tsx
│       ├── notifications.tsx
│       └── first-turn.tsx
├── (tabs)
│   ├── turn/
│   │   ├── index.tsx          — Turn home + input
│   │   ├── results.tsx        — Turn results display
│   │   ├── ritual-select.tsx  — Ritual template picker
│   │   └── ritual-flow.tsx    — Active ritual flow
│   ├── mirror/
│   │   ├── index.tsx          — Session list + new session
│   │   └── session.tsx        — Active Mirror session
│   ├── lens/
│   │   ├── index.tsx          — Goal dashboard
│   │   ├── create-goal.tsx    — 6-step goal creation
│   │   ├── goal-detail.tsx    — Goal detail + actions
│   │   └── rehearsal.tsx      — Rehearsal session
│   ├── gallery/
│   │   ├── index.tsx          — Pattern grid + filters
│   │   └── detail.tsx         — Pattern detail + share
│   └── you/
│       ├── index.tsx          — Profile + stats
│       ├── evidence-wall.tsx  — Evidence Wall mosaic
│       ├── spectrum.tsx       — Spectrum dashboard
│       ├── settings.tsx       — App settings
│       └── subscription.tsx   — Plan management
├── guide/
│   ├── checkin.tsx             — Check-in conversation (nested in Lens goal detail)
│   ├── checkin-summary.tsx     — Post check-in summary
│   ├── bridge-card.tsx         — Cross-feature bridge card (shared component)
│   ├── attention-prompt.tsx    — Daily attention prompt card
│   ├── moment-log.tsx          — Log a noticed moment
│   ├── evidence-card.tsx       — Evidence intervention card (used in Mirror + Turn)
│   └── pulse/
│       ├── index.tsx           — Weekly Pulse container (3-step flow)
│       ├── self-report.tsx     — Step 1: self-report
│       ├── ai-read.tsx         — Step 2: AI observations
│       └── next-focus.tsx      — Step 3: next week focus
└── (modals)
    ├── fragment-detail.tsx    — Half-sheet for fragment info
    ├── upgrade.tsx            — Prism upgrade prompt
    ├── crisis.tsx             — Crisis response (safety)
    ├── share-card.tsx         — Pattern card share sheet
    └── rate-limit.tsx         — Rate limit notice

Shared Components

Component Usage SVG Asset
FragmentIcon Everywhere — the core ◇ fragment-icons.svg
TabBar Main navigation icons-tab-bar.svg
DistortionBadge Mirror highlights, Gallery filters icons-distortions.svg
ActionIcon Buttons, list items, settings icons-actions.svg
KaleidoscopePattern Gallery, Turn result, share card patterns-kaleidoscope.svg
ProgressRing Lens goals, Rehearsal timer progress-indicators.svg
StepDots Lens 6-step, Ritual flow progress-indicators.svg
StreakCalendar Ritual tracking, You stats progress-indicators.svg
EvidenceMosaic Evidence Wall evidence-wall.svg
LoadingSpinner All loading states loading-animations.svg
SkeletonShimmer Data loading loading-animations.svg
TurnAnimation Turn processing loading-animations.svg
AIThinkingBubble Mirror AI processing loading-animations.svg
SuccessBurst Completion celebrations loading-animations.svg
BreathingLogo Splash, idle states loading-animations.svg
StatusBar Device chrome device-chrome.svg
NavHeader All screens device-chrome.svg
TabBarFrame Tab bar container device-chrome.svg
Toast Success/error feedback device-chrome.svg
InputAccessory Mirror, Turn text input device-chrome.svg
ShardCluster Empty states, backgrounds decorative-shards.svg
PrismaticDivider Section separators decorative-shards.svg
CornerAccent Card decorations decorative-shards.svg
SpectrumRiver Spectrum dashboard spectrum-visualizations.svg
SpectrumGlass Spectrum dashboard spectrum-visualizations.svg
SpectrumImpact Spectrum dashboard spectrum-visualizations.svg
SpectrumRhythm Spectrum dashboard spectrum-visualizations.svg
SpectrumGrowth Spectrum dashboard spectrum-visualizations.svg
GuideCard Bridge cards, evidence interventions, Guide notices — (CSS-only prismatic border)
GuideChat Check-in conversation interface — (reuses Mirror chat styling)
PulseScale Weekly Pulse self-report (5-point fragment scale) fragment-icons.svg

8. The Guide — Technical Specification

8.1 Database Schema

-- Guide check-in conversations
CREATE TABLE guide_checkins (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES users(id),
  goal_id UUID REFERENCES lens_goals(id),
  started_at TIMESTAMPTZ DEFAULT NOW(),
  ended_at TIMESTAMPTZ,
  plan_adjustments JSONB,  -- { old_plan, new_plan, reason }
  evidence_surfaced JSONB, -- array of proof point IDs shown
  summary TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Guide check-in messages (conversation history)
CREATE TABLE guide_checkin_messages (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  checkin_id UUID REFERENCES guide_checkins(id),
  role VARCHAR(10) NOT NULL CHECK (role IN ('guide', 'user')),
  content TEXT NOT NULL,
  sequence_order INTEGER,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Cross-feature bridge events
CREATE TABLE guide_bridges (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES users(id),
  bridge_type VARCHAR(20) NOT NULL CHECK (bridge_type IN ('discovery', 'reinforcement', 'integration')),
  source_feature VARCHAR(20) NOT NULL, -- 'mirror', 'turn', 'lens'
  target_feature VARCHAR(20),           -- what feature the bridge suggests
  trigger_data JSONB,                   -- { session_ids, turn_ids, theme, confidence }
  bridge_content TEXT,                  -- the displayed bridge text
  was_shown BOOLEAN DEFAULT FALSE,
  was_acted_on BOOLEAN DEFAULT FALSE,
  action_taken VARCHAR(50),             -- 'opened_lens', 'started_rehearsal', 'dismissed', etc.
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Daily attention prompts
CREATE TABLE guide_attention_prompts (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES users(id),
  goal_id UUID REFERENCES lens_goals(id),
  prompt_type VARCHAR(20) NOT NULL CHECK (prompt_type IN ('vision', 'capability', 'awareness', 'action', 'reflection')),
  manifestation_step INTEGER NOT NULL CHECK (manifestation_step BETWEEN 2 AND 6),
  prompt_text TEXT NOT NULL,
  delivered_at TIMESTAMPTZ,
  was_acknowledged BOOLEAN DEFAULT FALSE,
  moment_logged BOOLEAN DEFAULT FALSE,
  moment_text TEXT,
  moment_logged_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Evidence interventions
CREATE TABLE guide_evidence_interventions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES users(id),
  trigger_source VARCHAR(20) NOT NULL, -- 'mirror', 'turn'
  trigger_session_id UUID,             -- mirror_session_id or turn_id
  trigger_signals JSONB,               -- { signals detected: helplessness_language, etc. }
  evidence_shown JSONB,                -- array of proof point IDs surfaced
  intervention_text TEXT,
  was_shown BOOLEAN DEFAULT FALSE,
  was_acted_on BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Weekly pulse check-ins
CREATE TABLE guide_pulses (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES users(id),
  week_start DATE NOT NULL,
  self_report_score INTEGER CHECK (self_report_score BETWEEN 1 AND 5),
  self_report_text TEXT,
  ai_observations JSONB,   -- array of { observation, source, accent_color }
  divergence_note TEXT,     -- when self-report != AI read
  next_week_focus JSONB,    -- array of { suggestion, feature, reasoning }
  completed_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  UNIQUE(user_id, week_start)
);

8.2 API Endpoints

Endpoint Method Description Auth Rate Limit
/guide/checkins/:goalId GET Get check-in history for a goal JWT
/guide/checkins/:goalId/start POST Start a new check-in conversation JWT Free: 1/mo/goal, Prism: unlimited
/guide/checkins/:checkinId/message POST Send a message in check-in conversation JWT
/guide/checkins/:checkinId/complete POST End check-in, generate summary JWT
/guide/bridges GET Get pending bridge cards for user JWT
/guide/bridges/:id/action POST Record bridge action (shown, acted_on, dismissed) JWT
/guide/bridges/scan POST Trigger cross-feature pattern scan (background job) JWT Auto: daily
/guide/prompts/today GET Get today's attention prompt JWT
/guide/prompts/:id/acknowledge POST Mark prompt as seen JWT
/guide/prompts/:id/log-moment POST Log a noticed moment JWT
/guide/prompts/generate POST Generate next prompt (background job) JWT Auto: daily
/guide/evidence/check POST Check for evidence intervention triggers JWT Auto: after Mirror/Turn
/guide/evidence/:id/action POST Record intervention action JWT
/guide/pulse/current GET Get current week's pulse (or create if needed) JWT
/guide/pulse/:id/self-report POST Submit self-report score + text JWT 1/week
/guide/pulse/:id/ai-read GET Generate AI observations for the week JWT Prism only
/guide/pulse/:id/focus GET Generate next-week focus suggestions JWT Prism only
/guide/pulse/:id/complete POST Mark pulse as complete JWT

8.3 AI Pipeline

The Guide requires a cross-feature AI analysis pipeline that differs from single-feature calls:

Cross-Feature Context Window:

For check-ins, bridges, and the weekly pulse, the AI needs context from multiple features simultaneously:

Guide AI Context = {
  user_profile: { coaching_style, member_since, preferences },
  active_goals: [ { goal, milestones, if_then_plans, progress } ],
  recent_mirror_sessions: [ last 7 days — themes, fragment types, emotional tone ],
  recent_turns: [ last 7 days — topics, distortions, saved keepsakes ],
  evidence_wall: [ last 30 days — proof points by type and source ],
  ritual_data: { streak, consistency_score, last_completed },
  previous_checkins: [ last 2 check-ins per goal — summaries only ],
  previous_pulse: { last week's scores and focus areas }
}

Token estimate for cross-feature context: ~1,500-2,000 input tokens. With prompt caching (system prompt + stable user context cached), effective billable input drops to ~800-1,200 tokens per Guide call.

Background Jobs:

Job Schedule Purpose AI Model
Bridge Pattern Scan Daily (2am user-local) Analyze 7-day Mirror/Turn window for cross-feature patterns Haiku 4.5 Batch
Attention Prompt Generation Daily (5am user-local) Generate personalized prompt based on goal progress and manifestation step Haiku 4.5 (cached)
Evidence Trigger Check After each Mirror session / Turn Check session language for self-efficacy dip signals Haiku 4.5 (inline, fast)
Weekly Pulse AI Read On pulse open (lazy) Generate weekly observations from all feature data Haiku 4.5

Prompt Engineering Notes:

The Guide's system prompt must enforce:

  • Evidence-first framing (always lead with what went well)
  • Specific data references (numbers, dates, not vague encouragement)
  • Collaborative tone (propose adjustments, don't dictate)
  • Forward momentum (always end with next action)
  • Cross-feature awareness (reference Mirror/Turn patterns when coaching on Lens goals)
  • The user's selected coaching style (brutal honesty, gentle guidance, logical analysis, etc.)

8.4 Frontend Component Tree

screens/guide/
├── GuideCheckinScreen.tsx       — Check-in conversation (within Lens goal detail)
├── GuideCheckinSummary.tsx      — Post check-in summary card
├── GuideBridgeCard.tsx          — Reusable bridge card component (3 variants)
├── GuideAttentionPrompt.tsx     — Daily prompt card (within Lens dashboard)
├── GuideMomentLog.tsx           — Log a noticed moment screen
├── GuideEvidenceCard.tsx        — Evidence intervention card (used in Mirror + Turn)
├── GuidePulseScreen.tsx         — 3-step weekly pulse flow
│   ├── PulseSelfReport.tsx      — Step 1: self-report scale
│   ├── PulseAIRead.tsx          — Step 2: AI observations
│   └── PulseNextFocus.tsx       — Step 3: next week suggestions
└── shared/
    ├── GuideBorder.tsx          — Prismatic gradient border component
    ├── GuideIcon.tsx            — Faceted diamond with directional pulse
    └── FragmentScale.tsx        — 5-point fragment glow scale (for Pulse)

8.5 Rate Limiting (Guide-Specific)

Feature Free Prism
Goal check-ins rate:guide:checkin:{userId}:{goalId} — 1/month Unlimited
Cross-feature bridges Discovery only. rate:guide:bridge:{userId} — 1/day All types, 1/day
Attention prompts rate:guide:prompt:{userId} — 3/week Daily
Evidence interventions Blocked (Prism feature) rate:guide:evidence:{userId} — 1/session
Weekly pulse Self-report only Full 3-step with AI read

8.6 Push Notifications (Guide-Specific)

Notification Trigger Copy
Check-in reminder Scheduled per goal settings "Time to check in on [goal name]. How's it going?"
Attention prompt Daily at user's chosen time "Your Lens has a focus for today."
Bridge surfaced After daily bridge scan finds match "◇ A pattern is forming. Take a look."
Weekly pulse User's chosen day (default Sunday 7pm) "Your weekly Pulse is ready."
Moment log reminder 6 hours after prompt acknowledgment "Did you notice anything today?"