PRD: Optional Enneagram Assessment for Coach Personalization
Product: Objectuve (Enkidu) Feature: Enneagram personality assessment (opt-in) Status: ✅ Shipped (v1.18, 2026-05-14) Date: 2026-05-04 Owner: Josh Lockhart
Context
Objectuve's Coach already personalizes feedback using UserDetail jsonb fields (coach_persona, coach_tone_*, coach_depth, coach_focus_*, coach_rhythm) and AiEmployeeMemory injected into the system prompt at agent_runner/src/agent/promptBuilder.ts. These capture how a user wants to be coached (tone, frequency, focus) but not the underlying motivational structure — why a particular user resists, plateaus, or thrives.
The Enneagram is one of the few popular typologies that explicitly maps motivation and core fear/desire patterns, which translate cleanly into coaching framings (e.g., a Type 1 needs permission to be imperfect; a Type 7 needs help finishing rather than starting; a Type 4 needs continuity across mood swings). Adding an optional assessment gives Coach a richer, durable trait layer without requiring users to articulate it themselves.
The reference UX (Multifactor Enneagram) is a 40-question forced-choice format that resolves to scores across all 9 types plus wing/tritype/instincts. We'll mirror this structure but slim the result model and adapt the visual language to Objectuve's brand.
This is strictly optional and must not interfere with core flow. The product bet: users who self-select into a 5-minute assessment are signaling appetite for deeper coaching, and Coach output for those users should feel measurably more apt.
Goals & Success Metrics
Primary goals
- Give Coach a durable trait input that improves perceived feedback quality for opted-in users.
- Offer the assessment as a self-knowledge moment, not a gate or default.
Metrics
| Metric | Target | Notes |
|---|---|---|
| Assessment completion rate (of users who start) | ≥ 65% | 40 questions; abandonment is the main risk |
| Eligible-user start rate (dashboard card → start) | ≥ 18% | Card shown after 7 days of activity |
| Coach feedback "this felt accurate" rating, opted-in vs. not | +10pp lift | Measured via existing thumbs/feedback signal on Coach replies |
| Retake rate within 90 days | < 15% | High retakes signal poor confidence in result |
Guardrails
- Zero impact on signup/onboarding completion rate.
- No blocking modals, no notifications nudging the assessment.
- Coach quality for non-opted-in users must not regress (no shared prompt changes that assume Enneagram presence).
Non-Goals
- Therapeutic claims or clinical framing. The assessment is self-discovery, not diagnosis.
- Sharing types socially (no leaderboards, no "find your Type 4 friends," no community filtering).
- Replacing the existing
coach_persona/tone preferences. Enneagram is additive context, not a substitute. - Mandatory step in any flow.
User Stories
- As a 2-week-old user who's curious, I see a dismissible card on my dashboard offering a 5-minute personality assessment that will help my Coach understand me better.
- As a privacy-conscious user, I can permanently dismiss the dashboard card and still find the assessment in Settings → Personalization if I change my mind.
- As an opted-in user, my Coach references my type subtly (framing, not labels — e.g., "I know you'd rather start something new, but…" for a Type 7) without making me feel reduced to a category.
- As a user whose self-perception has shifted, I can retake the assessment from Settings, and prior results are preserved as history.
Scope
Assessment format
- 40 forced-choice question pairs, mirroring the reference test's structure.
- Single screen per question, two statement cards, tap to choose, auto-advance.
- Progress indicator (e.g., "12 / 40").
- Back button allowed; no required fields.
- Resumable: partial state persisted client-side; if abandoned, "Continue assessment" replaces "Start" on the dashboard card and settings entry.
- Question content authored fresh in Objectuve's voice rather than copied verbatim from the reference. 40-pair set with each pair scoring +1 to one of two competing types (each type appearing in ~9 pairs to balance exposure).
Result model
- Full 9-type scores (0–100 normalized), plus computed:
- Dominant type (1–9)
- Wing (adjacent type with higher score)
- Tritype (top type from each center: body 8/9/1, heart 2/3/4, head 5/6/7)
- Stored as a new
enneagram_assessmentstable (history retained per user). - Latest assessment is what Coach uses; prior results visible in Settings as a timeline.
Coach integration
- System-prompt injection — Add a "User personality profile" block to the agent system prompt builder when the user has a completed assessment. Format: dominant type + wing, top-3 type scores, and a curated 1–2 sentence framing per dominant type from a static lookup (authored once, brand-voice approved). Cap at ~250 tokens.
- Feedback templating — Where Coach generates streak-repair, milestone, and missed-day messages, expose the dominant type to template selection so type-aware framings can be authored over time. Initial release ships with system-prompt injection only; templating lands in a follow-up.
- User-visible self-knowledge — Settings → Personalization shows the user their result with a short, non-pathologizing description.
Discoverability
- Dashboard card — Appears once user has 7+ days of activity AND has not dismissed/completed the assessment. Dismissible (permanently). Lives alongside existing cards in Dashboard.vue with a
v-if="shouldShowEnneagramCard"gate, mirroringStreakRepairCard/GettingStartedCardpatterns. - Settings → Personalization — New tab in Settings.vue (added to the existing
tabsarray). Always available. Shows current result, retake button, and assessment history.
Out of scope (this version)
- Type-aware feedback templating (queued as v2).
- Explicit type filters in community/discovery surfaces.
- Coach acknowledging the assessment unprompted in conversation.
- Exporting results.
Design Notes
- Tone: the assessment is framed as a "5-minute self-portrait for your Coach," not a personality test. No quiz-app energy.
- Visual: glassmorphism question cards consistent with
docs/brand/brand.md. Single primary CTA per screen. Progress bar uses the primary gradient. - Result reveal: one screen, dominant type front and center with a 2–3 sentence description, expandable "see full breakdown" for the 9-type bars. No pop-ups, no confetti — quiet and respectful.
- Copy guardrails: never use the word "AI" in user-facing copy. Use "Coach." Avoid clinical/diagnostic language.
Implementation Outline (high-level — not a phase plan)
Backend
- Migration:
enneagram_assessments(user_id, scores jsonb, dominant_type, wing, tritype, completed_at, soft-delete viaacts_as_paranoid). - Model inheriting from
PublicRecord. SubmitEnneagramAssessmentinteraction (validates 40 answers, computes scores, persists row).- GraphQL:
enneagramAssessmentquery (latest),enneagramAssessmentHistoryquery,submitEnneagramAssessmentmutation. - Extend
agent_runner/src/agent/promptBuilder.tssystem prompt with a "User personality profile" section sourced from the latest assessment (passed in via the Rails-side run payload).
Frontend
- New view:
EnneagramAssessment.vue(question runner, resumable state vialocalStorage). - New components:
EnneagramQuestionCard.vue,EnneagramResultCard.vue,EnneagramHistoryList.vue. EnneagramPromptCard.vueon dashboard (gated by 7-day activity + opt-out flag).- New Settings tab:
panel-personalization. - Question bank:
src/constants/enneagramQuestions.ts(40 pairs, scoring map).
Telemetry
- Events:
enneagram_card_shown,enneagram_started,enneagram_completed,enneagram_abandoned(with question index),enneagram_retake_started,enneagram_dismissed. - Coach feedback signal already exists; segment by
has_enneagram_assessmentin dashboards.
Rollout
- Internal QA — admin/demo accounts complete the flow end-to-end; verify Coach prompt receives the profile block.
- Staging soak — at least one full real run with opted-in user, confirm Coach output reads naturally.
- Production — ship behind no flag (it's strictly opt-in by surface). Monitor completion rate and Coach feedback delta for 2 weeks before deciding whether to invest in v2 templating.
Open Questions
- Question bank authorship: adapt the reference 40 pairs (with significant rewriting for tone/IP separation) or commission an original set? Recommend original — cheaper than the IP/tone risk.
- Tritype value: surface tritype in the user-facing result, or keep it internal as Coach context only? Lean: internal only at launch (less to explain).
- Where exactly does the prompt block sit in
buildSystemPrompt? Above or belowAiEmployeeMemory? Decide during planning — likely above, since it's durable trait context.
Verification (post-implementation)
- Submit assessment as test user → confirm
enneagram_assessmentsrow created with valid 9-type scores summing to expected total. - Trigger a Coach run for that user → fetch the resolved system prompt → confirm "User personality profile" block is present and well-formed.
- Dashboard card visibility: seed a user with 6 days of activity (card hidden), 7 days (card shown), dismissed (card hidden), completed (card hidden).
- Settings → Personalization tab: shows latest result, history list, retake CTA. Retake produces a new row, latest is what Coach reads.
- Smoke test: full assessment completion path on staging.
Critical Files (anchors for future planning)
- agent_runner/src/agent/promptBuilder.ts — system-prompt injection point
- rails_api/app/models/user_detail.rb — adjacent personalization data model
- ionic_frontend/src/views/Dashboard.vue — dashboard card insertion
- ionic_frontend/src/views/Settings.vue — Settings tab insertion
- ionic_frontend/src/components/ui/AiCoachModal.vue — Coach UI (no changes in v1, future templating surface)
Related Documentation
- Enneagram Assessment — feature doc for the shipped implementation
Last updated: 2026-07-21 — Phase 100 audit. PRD for shipped feature (v1.18, Phases 77–81) archived to completed/.