Skip to content

Meet Coach -- Feature Exploration & PRD

Product: Objectuve (codename: Enkidu) Feature: Meet Coach -- personalized coaching configuration Status: Shipped — May 2026 Date: April 2026


1. Problem Statement

Objectuve has an AI Coach that provides context-aware advice, insight cards, check-in prompts, and milestone suggestions. But right now, users have no idea it exists until they accidentally tap a sparkle icon. And when they do find it, the Coach speaks in exactly one voice -- a hardcoded "coach who's also a friend" tone baked into every LLM prompt in CoachService.

Three problems:

  1. Discovery failure. Coach is arguably Objectuve's most differentiating feature -- a persistent, context-aware advisor. Yet the 5-slide onboarding wizard never mentions it. Users who'd benefit most during their fragile first week don't know it exists.

  2. One-size-fits-none coaching. A competitive athlete wants blunt accountability. Someone managing productivity anxiety wants gentleness. A college student building study habits wants energy and hype. The current fixed prompt is a reasonable middle ground that excels for nobody.

  3. Low engagement ceiling. Without personalization, Coach interactions feel generic. There's no moment where the Coach becomes their coach. This caps the feature's retention potential.

Meet Coach solves all three: introduces Coach during onboarding, lets users shape the coaching relationship, and creates a memorable moment that transforms "the app's AI" into "my Coach."


2. Goals & Success Metrics

Primary Goals

  1. Introduce Coach to 100% of new users
  2. Let users personalize coaching across four dimensions: persona, tone, focus area, frequency
  3. Increase Coach engagement by making the voice feel personal

Success Metrics

MetricTarget (90 days post-launch)
% of active users who've opened Coach modal at least once60%+
Coach configuration completion rate (from /meet-coach)70%+ of users who start
Weekly Coach interactions per active user2+ per week
Daily check-in prompt tap-through rate25%+
7-day retention lift for configured vs. unconfigured users+10pp

Guardrails

  • Flow must complete in under 90 seconds -- this is an anti-social app; configuration is not the product
  • No increase in daily session time from the configuration itself
  • Coach preference storage must not increase API latency for non-coach endpoints

3. User Stories

  • US-1: As a new user, I want to learn Coach exists during onboarding and optionally configure it, so I get personalized guidance from day one.
  • US-2: As a user on Meet Coach, I want to choose from distinct coaching styles with clear examples, so I pick the voice that motivates me.
  • US-3: As a user, I want to adjust how supportive vs. demanding Coach is.
  • US-4: As a user, I want to set focus priorities (streaks, milestones, reflection, accountability).
  • US-5: As a user, I want to control how often Coach reaches out.
  • US-6: As a returning user, I want to revisit /meet-coach from Settings to change preferences.
  • US-7: As an unconfigured user who opens Coach modal, I want a brief nudge to set up preferences.
  • US-8: As a configured user, I want advice/insights/check-ins to actually sound different based on my settings.

4. Feature Design

4a. Coaching Personas (The Archetypes)

Each persona represents a different coaching philosophy. Example messages respond to the same scenario: user missed 2 days of a 12-day streak on "Learn Spanish."


The Captain

Tagline: "Clear eyes, steady course." Tone: Calm authority. Concrete language -- numbers, dates, specific actions. Wastes zero words. Default focus: Milestones Example: "Two days off. Your 'Learn Spanish' streak was at 12 before the gap. Rebuild starts with one session today -- even 10 minutes counts toward a new run." Visual: Navy blue (#1e3a5f). Icon: compass.

The Spark

Tagline: "Energy is contagious -- starting now." Tone: High-energy enthusiasm that's specific, not hollow. Celebrates showing up more than outcomes. Default focus: Streaks Example: "Hey, you're back! That 12-day streak on 'Learn Spanish' showed you can build serious momentum. New streak starts today -- what's your first session going to be?" Visual: Bright orange (#f28529). Icon: lightning bolt.

The Mirror

Tagline: "The answer is usually already in your head." Tone: Reflective and question-driven. Rarely tells users what to do; asks questions that surface their own insight. Default focus: Reflection Example: "You had 12 days of consistent work on 'Learn Spanish' before this pause. What changed two days ago -- was it circumstance, or did something about the routine stop working?" Visual: Soft violet (#8b5cf6). Icon: ripple circles.

The Rival

Tagline: "You said you wanted this." Tone: Blunt accountability without cruelty. Treats users as capable adults who made commitments. Default focus: Accountability Example: "Twelve-day streak on 'Learn Spanish' -- gone. The gap happened; dwelling on it won't close it. Log a session today or decide this goal needs a different approach." Visual: Deep red-orange (#dc2626). Icon: target.

The Sage

Tagline: "Progress is a practice, not a performance." Tone: Warm wisdom. Takes the long view. Contextualizes setbacks as normal. Default focus: Reflection Example: "A 12-day streak is evidence that you can sustain effort on 'Learn Spanish.' Two days off doesn't erase that capacity -- it just means today is where you pick the thread back up." Visual: Warm gold (#b8860b). Icon: mountain.

The Analyst

Tagline: "The data tells a story." Tone: Pattern-focused and evidence-driven. References numbers, trends, comparisons. Suggests optimizations. Default focus: Milestones Example: "Your 'Learn Spanish' streak peaked at 12 days -- your longest yet. Looking at your check-in times, you were most consistent on weekday mornings. Worth scheduling today's session for that same window." Visual: Teal (#0d9488). Icon: chart/lens.


4b. Tone Spectrum

Single axis: Supportive <---> Demanding. Independent of persona -- modifies how hard the persona pushes. Stored as integer 1-5.

ValueLabelEffect
1GentleLead with what's going well. Frame suggestions as options.
2SupportiveWarm and encouraging. Acknowledge effort before suggesting.
3BalancedDirect but kind. Mix encouragement with honest assessment.
4DirectStraightforward, action-oriented. Name problems clearly.
5ToughBlunt. Hold user to stated commitments. No hedging.

Key insight: At Tone 5, The Spark still sounds like The Spark (energetic, forward-looking), not like The Rival. Persona = character; tone = intensity.

4c. Focus Area Priorities

Users select up to 2 focus areas (first tap = primary, second = secondary):

Focus AreaWhat Coach Emphasizes
StreaksDaily consistency, habit formation, showing up
MilestonesProgress toward checkpoints, completion rates, next steps
ReflectionPatterns, self-awareness, mood-to-progress connections
AccountabilityCommitments kept/broken, timeline adherence, honest assessment

Primary area's prompt text included in full; secondary adds shorter supplementary instruction.

4d. Communication Frequency

PresetCheck-in PromptsInsight Cards
Every dayDailyOn every page load
When I'm activeOnly on sign-in daysOn page load
When I need itOnly on streak break, milestone overdue, or 3+ days inactiveOnly on stalled pages
Milestones onlyOnly on milestone/streak milestones (7, 14, 30)Celebration-type only
MinimalNever auto-generatedNever; Coach modal only

GenerateAiCheckInPromptsJob gains a per-user frequency filter before the existing recent_ai_notification? check.


5. UX Flow

5a. First-Time Experience

3 sections on a single scrollable page (not a multi-step wizard). Target: under 60 seconds.

Section 1: Greeting + Persona Selection

  • Brief conversational Coach greeting (2-3 sentences, uses user.firstName)
  • 6 persona cards in 2-column grid. Each shows: name, tagline, colored icon, truncated example message
  • Tap to select; auto-scrolls to next section

Section 2: Tone + Focus

  • Tone slider -- 5-point segmented control ("Gentle" through "Tough"). Default: 3. Preview message updates per persona+tone combination (static, not LLM-generated)
  • Focus chips -- 4 pill buttons. First tap = primary (filled), second = secondary (outlined). One-line description updates below.

Section 3: Frequency + Confirmation

  • Frequency selector -- 5 radio-style cards, vertically stacked
  • Confirmation -- glassmorphism summary card showing all selections. "Save Preferences" CTA. "Skip for now" secondary link.

After saving: brief persona-appropriate greeting acknowledging the configuration.

5b. Return Visit (/meet-coach)

Summary view at top showing current configuration (persona card, tone, focus, frequency) with "Edit" affordances per section. "Reset to Defaults" link at bottom. Coach greeting acknowledges the revisit.

5c. Integration Points

Onboarding Wizard: New slide 4 (after Community, before First Goal). Lightweight intro: sparkle icon, "Your Goal Coach" headline, brief body, "Meet Your Coach" CTA (navigates to /meet-coach post-wizard) + skip option. totalSlides bumps from 5 to 6.

Settings Page: "Goal Coach" card added to Profile tab after Dashboard Mode. Shows current persona/tone/frequency. "Customize Coach" links to /meet-coach.

Coach Modal: Unconfigured users see a setup nudge in the welcome message + a suggested prompt chip linking to /meet-coach.

Daily Check-ins: Job reads preferences for frequency filtering and passes them to CoachService for personalized voice.


6. Data Model Changes

UserDetail already has a data JSONB column with store_accessor (see rails_api/app/models/user_detail.rb). Add:

ruby
store_accessor :data, :coach_persona         # "captain"|"spark"|"mirror"|"rival"|"sage"|"analyst"
store_accessor :data, :coach_tone            # 1-5 integer
store_accessor :data, :coach_focus_primary   # "streaks"|"milestones"|"reflection"|"accountability"
store_accessor :data, :coach_focus_secondary # same, nullable
store_accessor :data, :coach_frequency       # "daily"|"active"|"stuck"|"milestones"|"minimal"
store_accessor :data, :coach_configured_at   # ISO 8601 datetime

Why JSONB over columns on users: Preferences are read as a unit, consumed only by CoachService and frontend display. No individual indexes needed. Avoids migration on the high-traffic users table. UserDetail exists for exactly this.

Convenience method on User:

ruby
def coaching_preferences
  detail = details || create_details!
  {
    persona: detail.coach_persona || 'spark',
    tone: (detail.coach_tone || 3).to_i,
    focus_primary: detail.coach_focus_primary || 'streaks',
    focus_secondary: detail.coach_focus_secondary,
    frequency: detail.coach_frequency || 'daily',
    configured: detail.coach_configured_at.present?
  }
end

Defaults map to current hardcoded behavior. Zero change for existing users.

GraphQL Changes

  • New mutation: UpdateCoachingPreferences -- accepts persona, tone, focusPrimary, focusSecondary, frequency
  • New type: CoachingPreferencesType nested under UserType
  • New frontend constant in ionic_frontend/src/constants/graphql/ai.js

7. How Preferences Affect Coach Behavior

Prompt Preamble Architecture

New private method build_personality_preamble(user) in CoachService constructs a personality block prepended to each method's prompt:

You are a goal coach for Objectuve.
Your coaching persona is: [PERSONA_DESCRIPTION]
Tone calibration: [TONE_MODIFIER]
Focus priorities: [FOCUS_INSTRUCTIONS]

Core rules (always apply):
- 2 sentences max unless asked for more
- Never use motivational cliches
- Never guilt or pressure
- Reference specific goals/streaks/progress when available
- Be action-forward: tell the user what to DO, not how to FEEL

Each CoachService method gains an optional user: keyword. When absent, existing hardcoded prompt used as-is.

Concrete Examples (same get_advice call, different preferences)

Scenario: "Viewing goal 'Learn Spanish', 42% complete, 5 days left, last update 3 days ago"

  • Spark, Tone 2, Focus: Streaks: "You're nearly halfway through 'Learn Spanish' and you've been quiet for three days -- but that 42% is real progress. A quick session today gets your rhythm back."
  • Rival, Tone 5, Focus: Accountability: "42% done on 'Learn Spanish' with 5 days left and no activity for 3 days. That math doesn't work unless you hit at least one milestone per day from here."
  • Mirror, Tone 1, Focus: Reflection: "Three quiet days on 'Learn Spanish' after steady progress to 42%. What shifted -- was it the goal itself, or did something else pull your attention?"

8. Edge Cases & Open Questions

Edge Cases

#ScenarioResolution
EC-1No UserDetail recordcoaching_preferences does find_or_create. Defaults ensure valid inputs.
EC-2User leaves without savingUnsaved state lost. Standard behavior.
EC-3Persona identifier renamed in futureMap retired identifiers to nearest replacement at read time.
EC-4LLM provider varianceUse explicit behavioral instructions ("ask questions") not abstract adjectives ("be reflective"). Test all providers.
EC-5The Rival at Tone 5 feels harsh"Core rules" guardrail (never guilt/pressure) is the safety net. QA must test sensitive scenarios.
EC-6Persona change mid-conversationClear history in useAiCoach.ts when preferences change (method already exists).
EC-7MockLlm fallbackUpdate to include persona-aware mock or at minimum not crash with preferences.

Open Questions

  1. Live preview vs. static examples on persona cards? Recommend static for MVP -- live adds latency for a screen visited once.
  2. Default persona for unconfigured users? Recommend The Spark at Tone 3 -- closest to current hardcoded voice.
  3. XP reward for completing setup? Suggest 50 XP + "Coach's Pick" badge via UserAction.generate.
  4. Frequency filtering in SQL vs. Ruby? Ruby-level (check each user in loop) is simpler, maintains existing job structure, fine for current scale.
  5. Offline/Ollama model fidelity? Smaller models may follow persona instructions poorly. Recommend: don't surface provider warnings; let it work as well as each model allows.

9. Implementation Phases

Phase 1: MVP -- "Meet Coach Exists" (1-2 sprints)

Backend:

  • Add store_accessor fields to UserDetail
  • Add coaching_preferences method to User
  • Create UpdateCoachingPreferences mutation + CoachingPreferencesType

Frontend:

  • Create MeetCoach.vue page at /meet-coach
  • Add route to router
  • Add "Goal Coach" card to Settings Profile tab
  • Add GraphQL mutation constant

Coach Integration (minimal):

  • Add build_personality_preamble to CoachService
  • Modify get_advice to accept user: and prepend preamble
  • Update useAiCoach.ts welcome message for unconfigured users

NOT in Phase 1: Onboarding slide, check-in personalization, insight personalization, XP reward.

Phase 2: Full Personalization (1 sprint)

  • Inject preamble into generate_insight, generate_check_in_prompt, refine_description
  • Update GenerateAiCheckInPromptsJob with frequency filtering + preference passing
  • Add Coach slide to OnboardingWizard.vue (new slide 4, totalSlides = 6)
  • Award "Coach's Pick" badge + 50 XP on configuration

Phase 3: Polish & Measurement (1 sprint)

  • Add UserAction milestones for coach configuration events
  • Instrument Coach interactions with persona/tone metadata
  • Return-visit state for /meet-coach (summary view with edit)
  • QA across all LLM providers
  • Consider live tone preview

10. Design Suggestions

Layout: Full-bleed ion-content, bg-secondary/30, content max-w-lg mx-auto, px-5 py-6. Glassmorphism Card components.

Persona Cards: 2-column grid. Unselected: bg-card/50 backdrop-blur-sm border. Selected: border-2 border-primary ring-2 ring-primary/20 with persona accent color left-bar. 48x48 rounded avatar with gradient + Lucide icon.

Tone Slider: 5-segment control (not continuous). Active: bg-primary text-white. Preview card below updates per combination.

Focus Chips: Pill-shaped row. Primary: bg-primary text-white. Secondary: border-primary text-primary bg-primary/10.

Frequency: Vertical radio-card stack. Selected: border-primary bg-primary/10 ring-2 ring-primary/20 + checkmark.

Animations: Staggered pop-in on persona cards. fade-in slide-in-from-bottom on sections. Confetti on save.

Accessibility: role="radiogroup" on persona/frequency. role="slider" on tone. role="checkbox" on focus chips. Accent colors on borders/icons only (not text).


Critical Files

FileChange
rails_api/app/models/user_detail.rbAdd coaching preference store_accessors
rails_api/app/models/user.rbAdd coaching_preferences convenience method
rails_api/app/services/ai/coach_service.rbAdd build_personality_preamble, modify methods to accept user:
rails_api/app/graphql/mutations/New UpdateCoachingPreferences mutation
rails_api/app/graphql/types/New CoachingPreferencesType
rails_api/app/jobs/ai_coaching/generate_ai_check_in_prompts_job.rbFrequency filtering (Phase 2)
ionic_frontend/src/views/MeetCoach.vueNew standalone page
ionic_frontend/src/router/index.tsAdd /meet-coach route
ionic_frontend/src/views/Settings.vueAdd "Goal Coach" card to Profile tab
ionic_frontend/src/constants/graphql/ai.jsNew mutation constant
ionic_frontend/src/composables/useAiCoach.tsPreference-aware welcome messages
ionic_frontend/src/components/onboarding/OnboardingWizard.vueNew Coach slide (Phase 2)

  • Meet Coach — feature & configuration guide for the shipped implementation

Last updated: 2026-07-15

Loading…