Onboarding Quiz Spec
Task
Using this design specification, produce uvilo_onb_general.json — a complete onboarding quiz. The quiz must: gate 5 conditional domains (via 4 questions, with Work and Business combined), probe foundational life skills via scenario-based MC, capture motivation and readiness, surface durable personal knowledge for factoid extraction, and identify life priorities. Target 20–25 questions. Output valid JSON only.
Quiz Metadata
The instructions field carries the oracle framing — it is the first text the user reads. Write it in the voice described in the Voice & Tone Guide below.
Future variants (e.g., men, women, demographic splits) will use different handles (onb_men, onb_women) but the same evaluation output contract. The current scope is the general quiz only.
Five Purposes
This quiz serves five distinct purposes. Every question must serve at least one.
- Domain gating — Determine which of the 5 conditional domains (School, Work, Business, Parenting, Caregiving) are active for this user. Work and Business are gated by a single MC question.
- Life skills probes — Indirectly measure foundational skills via scenario-based MC. Reveal awareness baselines, not self-reported status.
- Motivation & readiness — Capture what brought the user to Uvilo and their openness to change.
- Life priorities — Identify which life areas feel most pressing, to determine which domain quiz to take first.
- Factoid extraction — Surface durable personal knowledge (living situation, formative experiences, major transitions, support network) that feeds the factoid memory system for all future conversations and evaluations.
Scoring Philosophy
The onboarding quiz bypasses The Grade and The Bracket entirely. The only output that matters is The Evaluation — an AI-generated qualitative assessment driven by evalHint fields.
Numeric scores exist for schema compliance:
- Probes: Higher score = more coaching-ready response. The evaluation agent references scores as lightweight signal but relies on
evalHintfor interpretation. - Gating questions: Weight: 0. Neither answer is “better.” Pure routing.
- Factoid questions: Weight: 0 or 1. Value is in text content, not numeric score.
- Motivation/priority questions: Low weight. Value is qualitative.
MC options should be ordered from most to least coaching-ready with monotonically decreasing scores, but the evaluation agent relies on evalHint rather than raw scores.
evalHint System
Two fields drive the evaluation:
quizQuestion.evalHint (per-question)
Currently used only for freeform question evaluation. The hint is appended to the system prompt of the freeform question eval bot, which evaluates one question at a time. For each question, describe what the question is designed to surface and how the evaluation agent should interpret different answers.
Example (probe):
Example (factoid):
Example (MC with factoid extraction):
Factoid extraction wording in MC evalHints
Every MC question evalHint should end with a Factoid extraction: block that guides the extraction bot on what to store for each answer option. Use synthesis-prompting language — tell the bot what to note, not what words to use:
- ✅ Do:
"If B, note that they show up for exercise but without intrinsic motivation." - ❌ Don’t:
"If B, store that user will exercise but lacks enthusiasm for it."
The second form causes the bot to parrot the evalHint text verbatim into the factoid, producing quiz-transcript-style notes instead of natural-language coach observations. The first form gives the bot latitude to phrase the factoid in its own words while preserving the intended content.
For freeform questions, the factoid block should specify what elements to extract and whether to store them as separate factoids (e.g., “Store each routine element as a separate factoid”).
quiz.evalHint (quiz-level)
Specifies the evaluation output contract. The evaluation agent must produce a JSON object conforming to the OnboardingEvaluation schema (see below). The quiz-level evalHint should instruct the evaluation agent to:
- Categorize questions by purpose using handle prefixes (
gate_,probe_,mot_,fact_,pri_) - For probes (
probe_), organize findings by domain intostructuredAnalysis.skillGaps - For motivation (
mot_), synthesize intostructuredAnalysis.motivationProfile - For priorities (
pri_), derivestructuredAnalysis.prioritiescross-referenced with probe and factoid content - For gating (
gate_), determineactiveDomainIdsusing per-question evalHint routing logic - Produce
factoidsfrom ALL question types — gating answers, probe selections, freeform responses, and motivation/priority answers. Every answer potentially contains a durable personal fact. - Produce
profileFieldsfor any data that should be written to the user profile - Write
userEvaluationas a warm, oracle-voiced markdown summary (150\u2013300 words) - Optionally tag
structuredAnalysis.uviloTagswith taxonomy references for cross-referencing with conversation summaries
Factoid extraction process
Factoid extraction is handled by the standard pipeline, not by the evaluation agent. The quiz output is converted to a synthetic AI chat: questions become assistant messages, answers become user messages (for non-freeform questions, the answer label is used), and question evalHints become system messages inserted between the assistant/user pairs. The factoid extraction bot then processes this synthetic conversation like any other.
All question types produce factoids, not just freeform. A gating answer (\u201cYes, I\u2019m a parent\u201d) is a factoid. A probe selection (the user chose the avoidance coping style) reveals a behavioral pattern. Question evalHints provide the extraction bot with context about what each answer reveals beyond its literal text.
Factoid wording quality matters. The evalHint\u2019s Factoid extraction: block shapes how the bot phrases each factoid. If the block says \u201cstore that user prefers data-driven, metrics-based self-improvement and already tracks parts of his life with spreadsheets and gadgets,\u201d the bot will produce that exact sentence as a factoid \u2014 parroting the quiz transcript rather than writing a natural observation. Use synthesis-prompting language (\u201cnote their data-oriented personality and any self-tracking habits\u201d) so the bot writes factoids that sound like a coach\u2019s notes, not like a quiz answer key. See the \u201cFactoid extraction wording in MC evalHints\u201d section above for examples.
The evaluation agent\u2019s factoids array in the output schema is a secondary extraction pass that captures factoids the pipeline might miss based on cross-question analysis. Both sources feed into the same factoid memory system.
Evaluation Output Schema
The quiz evaluation produces a JSON object with five root-level fields, each routed to a different storage destination:
| Field | Type | Destination |
|---|---|---|
structuredAnalysis | object | Stored with quiz result for AI coach reference |
profileFields | array | Written to user profile |
factoids | array | Entered into factoid memory system |
userEvaluation | string | Displayed to the user (markdown) |
activeDomainIds | string[] | Domain routing (consumed by multiple systems) |
Zod schema: OnboardingEvaluationSchema.ts (co-located with this spec)
Voice & Tone Guide
Voice Brief
A wise oracle who doesn’t take themselves too seriously. A friend who happens to be a therapist — insightful questions delivered with a wink. Never clinical, never condescending, occasionally surprising. Occasionally funny.
Tone Rules
- Scenario questions: present tense, second person (“You receive…”, “Your friend tells you…”)
- Answer options: first-person, conversational (“I\u2019d immediately…”, “Honestly, I\u2019d probably…”)
- Avoid survey language: no “How would you rate…”, “On a scale of…”, “How often do you…”
- Freeform prompts: direct and warm (“Tell us about…”, “What\u2019s the first thing that comes to mind when…”)
- Gating questions: playful but clear — still need unambiguous yes/no answers
- The
instructionsfield carries the oracle framing — first text the user reads
Anti-Patterns
| ❌ Don\u2019t | ✅ Do |
|---|---|
| ”How would you rate your sleep quality on a scale of 1-10?" | "It\u2019s 11 PM on a Tuesday. What\u2019s actually happening?" |
| "Do you have children? Yes / No" | "Are you responsible for raising a tiny (or larger) human — or expecting one?" |
| "Describe your financial situation." | "You find $5,000 in an envelope with your name on it. What\u2019s your first move?" |
| "How important is community to you?" | "A friend you haven\u2019t heard from in months calls out of the blue. What do you do?" |
| "What are your goals?" | "If you could wave a magic wand and fix ONE thing in your life tomorrow, what would it be?” |
What This Quiz is NOT
- Not a knowledge test — don\u2019t make people feel stupid for picking \u201cwrong\u201d answers. Every answer option should feel like a valid, human response. MC options should not be transparently ranked from \u201cenlightened\u201d to \u201cbroken\u201d \u2014 all four should read as things a reasonable person would actually say or do. The scoring happens invisibly; the user should never be able to guess which answer is \u201cbest.\u201d
- Not a self-report survey — avoid \u201cHow would you rate your\u2026\u201d phrasing. That\u2019s for domain quizzes.
- Not comprehensive — it\u2019s a lightweight probe, not a full assessment.
- Not clinical — avoid diagnostic language, screening tools, clinical terminology.
- Not judgmental — frame every answer option as something a reasonable person would say or do.
Structure
Single section containing all questions. No logical section divisions visible to the user — the experience is a flat stream of rapid-fire, seemingly random questions that together create the feeling of a mysterious method behind the design.
Ordering Principles
- Gating before gated content — each gating question must appear before any question that depends on the gated domain. But gating questions do NOT need to be grouped together at the start. Interleave them with probes and factoids so the quiz opens with variety and energy, not a block of yes/no questions.
- Curate a pseudo-random order — alternate between probe, factoid, gating, and motivation questions. Mix domains so adjacent questions feel unrelated. The quiz should feel like a mysterious stream of seemingly random questions, not a categorized form.
- Never place two freeform questions consecutively.
- End with something memorable — the last question should leave the user feeling intrigued or thoughtful, not like they just finished a form.
Use a single section in the JSON:
Question Budget
| Category | Count | Question Types | Primary Purpose |
|---|---|---|---|
| Domain gating | 4 | boolean or MC | Determine active domains (Work+Business combined) |
| Life skills probes | 9–12 | mostly MC (scenario-based) | Skill baselines via evalHints |
| Motivation/readiness | 2 | 1 MC + 1 freeform | Why here, openness to change |
| Factoid/personal knowledge | 3–5 | mostly freeform | Durable facts for memory system |
| Life priorities | 1–2 | freeform | Which areas to focus first |
| Total | 20–26 |
Freeform ratio deviation
The standard domain quiz freeform target is 16–22%. The onboarding quiz will likely reach ~25–35% because factoid questions are inherently freeform and this quiz prioritizes qualitative data and factoid extraction over scoring. This deviation is intentional and accepted.
Domain Gating
Four gating questions cover five conditional domains. Work and Business are combined into a single MC question since employment type naturally distinguishes them.
| Domain(s) | domainId(s) | Gating Strategy |
|---|---|---|
| School | school | Currently enrolled in formal education? |
| Work + Business | work, business | MC: employed / employed + side hustle / self-employed or freelance / between jobs / not applicable. “Employed” → activate work. “Employed + side hustle” → activate both work and business. “Self-employed/freelance” → activate business. “Between jobs” → activate work. “N/A” → neither. |
| Parenting | parenting | Parent, guardian, or expecting? |
| Caregiving | caregiving | Regular care for aging parent, disabled family member, or other dependent? |
Gating questions use weight: 0 and equal scores for all answers (neither is “better”). Pure routing. Write them in the oracle tone — playful but unambiguous.
The evalHint for each gating question should state the routing logic clearly: which answer values activate which domainIds.
Gating questions are not required to be booleans — MC is appropriate when a single question can gate multiple domains (as with Work + Business).
Probe Allocation
Probes are weighted by domain, not evenly distributed. Up to 3 for foundational domains, 0 for domains better served by factoid questions.
| Domain | Probes | Probe Candidates | Notes |
|---|---|---|---|
| Body | 2–3 | Sleep hygiene, nutrition mindset, movement relationship | Foundational. High coaching ROI. |
| Mind | 2–3 | Emotional granularity, thought-feeling distinction, stress response | Core life skills. |
| Home | 0 | — | Replace with factoid: living situation (alone/partner/family/roommates/homeless). Factoid is more valuable than a probe. |
| Community | 1–2 | Active listening vs. fix-it mode, boundary-setting | Social skills baseline. |
| Money | 1 | Emergency fund concept or financial hierarchy awareness | |
| Play | 1 | Permission to rest / guilt relationship | |
| Growth | 1 | Growth vs. fixed mindset | |
| Purpose | 1 | Values clarity / articulation |
Probe design principles
- Use scenario-based MC where the answers reveal awareness or behavioral tendency, not “right answers.”
- Scenario completeness: Every scenario must have an answer option for every plausible human in the target audience. If a scenario assumes the user is awake at a certain hour, broke, in a certain living situation, etc., include an option for people who don\u2019t fit that assumption.
- Answer camouflage: All MC answer options should feel equally valid and human. A user should not be able to rank the options by “correctness” on sight. Avoid the pattern where option A is obviously the therapist-approved answer and option D is obviously the dysfunctional one.
- evalHints should describe what each answer choice reveals about the user\u2019s baseline in that skill.
- If a probe naturally surfaces factoids (e.g., the living situation question for Home), tag it as dual-purpose.
Factoid Question Design
What makes a good factoid question
Good factoid sources (durable, reusable):
- Living situation (alone, partner, family, roommates, homeless)
- Formative life experiences and how they shaped the user
- Chronic health conditions or disabilities
- Major life transitions in progress (divorce, career change, new baby, retirement, grief)
- Cultural or religious practices that shape daily life
- Support network (close support or isolated?)
- Work/career beyond gating (industry, satisfaction, stability)
Poor factoid sources (exclude):
- Current mood or emotional state (transient)
- Specific goals (captured in domain quizzes)
- Detailed financial information (too sensitive at onboarding)
- Anything already in user profile (age, gender, location, relationship status)
Example factoid questions
- “Describe one important formative experience in your life, and how it affected you.”
- “Who are the 2-3 people you\u2019d call at 2 AM if everything went sideways?”
- “What does a typical weekday evening look like for you, from the time you get home?”
Handle Convention
All question handles use the prefix onb_general_ to namespace within the global handle space and allow future quiz variants (e.g., onb_men_, onb_women_) to reuse some handles without conflict.
After the quiz prefix, a purpose prefix identifies the question\u2019s role. This is how the evaluation agent categorizes questions by purpose without requiring extra fields in the quiz schema.
| Purpose | Prefix | Example |
|---|---|---|
| Domain gating | gate_ | onb_general_gate_school |
| Life skills probe | probe_ | onb_general_probe_sleep |
| Motivation/readiness | mot_ | onb_general_mot_why_here |
| Factoid extraction | fact_ | onb_general_fact_living |
| Life priorities | pri_ | onb_general_pri_wand |
Handles must be 3\u201332 characters, snake_case. With the onb_general_ prefix (12 chars) plus purpose prefix (4\u20136 chars), 14\u201316 characters remain for the descriptive portion. Keep handle names concise.
Known Data (Do Not Re-Ask)
The user profile already contains: email, name, DOB (→ age), gender, relationship status, timezone, location, citizenship. The onboarding quiz should not re-ask any of these.
Schema Conventions That Apply
From the life_domain_quiz skill (Domain_Quiz_Prompt.md):
- JSON structure: Same schema (group, slug, handle, version, date, name, description, instructions, sections). Add
evalHintat quiz level and per-question. - Question types: boolean, multiple_choice, scale, freeform — same definitions.
- Boolean style: Answers begin with “Yes”/“No”, comma for continuation.
- Scale anchors: value “0” and value “10” with appropriate score direction.
- MC ordering: Best → worst, monotonic scores.
- Smart typography: Typographic quotes \u201c \u201d and apostrophes \u2019. Literal UTF-8 characters, not Unicode escapes.
- Handle rules: snake_case, 3–32 characters, globally unique.
- Branching logic: filterQuestion/filterValues work as documented in the skill. Use where appropriate (e.g., gating → follow-up).
Conventions overridden for this quiz
- Freeform ratio: ~25–35% instead of 16–22%. Justified by factoid extraction priority.
- Scoring significance: Scores are secondary to evalHints. No Grade or Bracket.
- Section structure: Single section, pseudo-random ordering.
- Weight: 0 is valid for gating and factoid questions where numeric scoring is irrelevant.
- \u22651 freeform per section: Not applicable — there\u2019s only one section. Aim for freeforms well-distributed across the question stream.
Open Decisions (Resolve During Build)
Work gating: Binary boolean or 3-option MC?Resolved: Combined Work + Business into a single MC with 4 options (employed / self-employed or freelance / between jobs / N/A). Self-employed activates both Work and Business domains.- Life priorities: Explicit freeform question(s), or inferred from probe + factoid + motivation answers? (If inferred, the quiz-level evalHint must instruct the agent to derive priorities from the other answers.)
- Intimacy probe: Include a communication/conflict style probe applicable regardless of relationship status?
- Gating follow-ups: Should any gating “Yes” answers trigger a freeform follow-up (e.g., “Tell us briefly about your business”)?
Conditional Domain Reference
For activeDomainIds in the evaluation output:
| # | domainId | id | Conditional |
|---|---|---|---|
| 1 | body | dim_ca1e3d38edc1f992d087387 | No |
| 2 | mind | dim_ca1e3d38e4e68e9ed0f2f6a | No |
| 3 | home | dim_ca1e3d38e0f5d54e00cb536 | No |
| 4 | intimacy | dim_ca1e3d38eb53dbe7800edc7 | No |
| 5 | community | dim_ca1e3d38ec959f609053472 | No |
| 6 | school | dim_ca1e3d38e2c145a61060f84 | Yes |
| 7 | work | dim_ca1e3d38e581bbb3c0639b3 | Yes |
| 8 | business | dom_cmlekp5p500cbq1uyzv57ssdu | Yes |
| 9 | money | dim_ca1e3d38e7c49558b0a3b8a | No |
| 10 | parenting | dim_ca1e3d38eab2c7849002c7a | Yes |
| 11 | caregiving | dom_cmlekp6l200ccq1uyg0ztdjdb | Yes |
| 12 | play | dim_ca1e3d38ed5baab7105bafc | No |
| 13 | growth | dim_ca1e3d38e40ae678108eed3 | No |
| 14 | purpose | dom_cmlekp7iy00ceq1uyj1elp6gj | No |
The evaluation output should use domainId strings (e.g., "body", "school") in the activeDomainIds array.
Next Step
Phase 3: Build. Produce uvilo_onb_general.json containing:
- Complete quiz metadata with oracle-toned
instructionsand quiz-levelevalHint - All questions with handles, answers, scores, weights, and per-question
evalHint - Validate against the quiz schema (extended with evalHint fields)
- Run the QC checker and fix any issues