Skip to content
Visibility internal Owner _ Approver _ Created _ Updated _

Domain Quiz Spec

What this is

A Life Domain Quiz is Uvilo’s mixed-methods assessment for one of the Domains of Life Balance. It captures both quantitative signals (boolean, multiple-choice, scale) and qualitative context (free-form) so coaches can prioritize work, set goals, and personalize plans.

What it does

  • Surfaces a client’s current status, behaviors, and attitudes within a single domain.
  • Balances scoreable items (for roll-ups, trends, comparisons) with narrative prompts (for nuance, motivations, constraints).
  • Produces a single JSON object per domain that downstream tools can parse to score sections, weight questions, and generate insights.

How it’s structured (data model)

  • A dimension JSON has top-level metadata (group, slug, handle, version, date, name, description, instructions, analysisBotHandle) and an array of sections.
  • analysisBotHandle identifies which analysis bot processes quiz results. Life domain quizzes use "analyze-life-domain-quiz"; the onboarding quiz uses "analyze-onboarding-quiz". This field is required.
  • Each section has name, handle, and an ordered list of questions.
  • Each question has handle, type (boolean | multiple_choice | scale | freeform), question, maxScore, weight, and—when applicable—answers.
  • Optional question fields: filterQuestion, filterValues, autoFill (branching logic — see below), and evalHint (optional string providing guidance to the analysis bot on how to interpret the answer).
  • Scoring convention: higher is always better.
  • boolean typically uses maxScore: 7 with two answers beginning “Yes” / “No”.
  • multiple_choice and scale typically use maxScore: 10.
  • scale questions include two anchor answers only: value “0” and value “10”. The score for each anchor depends on question direction — for positive questions (higher = better), value “0” gets score 0 and value “10” gets score 10. For inverse questions where higher is worse (e.g., “How often do you feel lonely?”), value “0” gets score 10 and value “10” gets score 0.
  • multiple_choice options are monotonic in score (clearly ordered).
  • freeform questions carry maxScore/weight for consistency but are used for qualitative analysis.

When you are updating an existing domain

  • Preserve existing slugs and metadata whenever possible.
  • Fix wording, scoring inversions, ordering, and typography without changing the intended content.
  • Enforce the established conventions (boolean label style, scale anchors, MC monotonicity, smart quotes).
  • Aim for ~20% freeform (acceptable 16–22%), with at least one freeform per section where feasible.
  • Split any compound prompts into separate items if they conflate distinct constructs (e.g., “strength, endurance, flexibility”).
  • Order factual booleans before broad freeform prompts within a section.
  • Add filterQuestion/filterValues to skip questions that don’t apply (e.g., skip “Describe your conditions” when the user answered “No” to having conditions).
  • Set autoFill on freeform questions only where existing knowledge (prior quiz results or factoid memory) can pre-populate the answer, reducing respondent fatigue. Usually, this is for long-term things like chronic conditions or allergies, not evaluations of the user’s current transient state. Never set autoFill on boolean, scale, or MC questions.
  • When a freeform has autoFill, implement the full back-fill pattern: the boolean gate sets filterQuestion to the freeform’s handle with filterValues: [], so the gate is skipped when the freeform already has a stored value. See Rule 14 for the complete pattern.

When you are creating a new domain from scratch

  • Follow the same structure and conventions above.
  • Keep handles in snake_case, keep language plain and actionable, and ensure higher score = better.
  • Handles must be globally unique (among all the quizzes)
  • Use smart typography inside strings (typographic quotes ” ” and apostrophes ’).
  • Distribute weight reasonably across questions; keep consistency with existing domain patterns unless there’s a strong reason to diverge.

Output requirements for the model

  • Return only the updated/created domain JSON (no commentary), valid and parseable.
  • Ensure it passes a checklist of rules (freeform share, boolean label style, scale anchors, MC monotonicity, verb consistency, ordering, typography).

Apply the following rules exactly

  1. Domain tag coverage
  • Before writing or reviewing questions, load the domain’s tags array from LifeDomainData.json.
  • Every tag must be addressed by at least one question. If a tag is missing, add a question or note the gap.
  • Tags define the minimum coverage boundary; questions may go beyond tags but must not leave any tag uncovered.
  1. Instrument mix & proportions
  • Keep a blend of question types: boolean, multiple_choice, scale, and freeform.
  • Maximum 40 questions per quiz.
  • Target ~20% freeform within the domain (acceptable band 16–22%).
  • Compute target = round(0.2 × total_questions).
  • Ensure at least one freeform per section whenever feasible.
  1. Where to use freeform vs structured
  • Freeform for nuance: goals/intentions, obstacles/barriers, future concerns, support/community roles, personal definition of success/meaning, anything that can’t be captured by a short list without loss.
  • Multiple choice for frequencies, selectable categories, and “best description” prompts with a small, well-defined option set.
  • Scale for self-ratings (satisfaction, confidence, alignment, consistency, intensity).
  • Boolean for clean yes/no states (screenings, basic behaviors, simple presence/absence).
  1. Wording & typography
  • Use typographic quotes (” ”) and apostrophes (’). Replace straight quotes.
  • Keep verb usage consistent between question and answers (e.g., if the question says “handle stress,” answers use handle, not manage).
  • Use clear, plain language with minimal jargon. Prefer “How often…”, “How would you rate…”, “What best describes…”.
  1. Boolean answer style
  • Every boolean question must have answers beginning with “Yes” and “No”.
  • If adding detail, use a comma after Yes/No: “Yes, …” / “No, …”.
  • Do not use em/en dashes after Yes/No (e.g., avoid “Yes – …”).
  1. Scale answer anchors
  • For every scale question, include an answers array with two entries for value “0” and value “10”.
  • For positive questions (higher value = better): { “value”: “0”, “score”: 0 } and { “value”: “10”, “score”: 10 }.
  • For inverse questions measuring negative frequency or intensity (e.g., “How often do you feel lonely?”, “How stressed do you feel?”): { “value”: “0”, “score”: 10 } and { “value”: “10”, “score”: 0 }. This ensures higher score = better even when higher value = worse.
  • Labels must unambiguously signal the poles (e.g., “Not at all confident” vs “Extremely confident”).
  1. Multiple-choice quality
  • Choices should be mutually exclusive, collectively sufficient, and ordered from best→worst or most→least (whichever fits), with monotonic scoring.
  • Fix awkward or ambiguous options (“Rarely manage”) by aligning with the question verb or rephrasing (“Rarely handle it well”).
  1. Ordering logic
  • Put specific screening/boolean items before broad freeform capture to avoid leading responses and to collect factual baselines first.
  • If a freeform field asks users to “list” items, precede it with any simple presence/absence booleans that narrow scope (e.g., “Do you have allergies?” before “Please list …”).
  • Exception for filter gates: When a boolean serves as a filter gate, place its dependent questions immediately after it so that skipped questions are visually grouped with their gate. This overrides the general “booleans before freeforms” guideline — filter adjacency takes priority.
  1. Splitting compound constructs
  • If a question conflates distinct constructs (e.g., strength/endurance/flexibility), split into separate items (prefer scale with 0/10 anchors).
  • Preserve the original weighting intent by distributing or keeping small, equal weights (e.g., each sub-item gets weight: 1).
  1. Scoring sanity & direction
  • Higher score = better status/behavior across the board.
  • Correct any inverted mappings (e.g., avoidance of harmful behavior should score higher on “Yes”).
  • Keep existing maxScore/weight unless a fix is clearly necessary:
  • boolean commonly maxScore: 7
  • scale and multiple_choice commonly maxScore: 10
  • Use weights already present; if adding splits, keep weights modest and balanced.
  1. Handles
  • Keep existing handles; add new handles in snake_case.
  • Handles must be 3–32 characters, globally unique across all quizzes.
  • Derive the handle from the question text: use key content words, omit filler words (do, you, have, the, a, how, what, your, etc.), and abbreviate where natural. Examples: “Do you have any chronic medical conditions?” → have_medical_conditions; “How would you rate your overall physical fitness?” → rate_overall_fitness; “Please describe your current sleep routine” → describe_sleep_routine.
  1. Style, and consistency
  • Use en dashes for ranges (e.g., 4–6); avoid double spaces.
  • Ensure all final strings use smart quotes / apostrophes.
  1. Deliverables
  • Return only the updated domain JSON.
  • Do not include commentary or markdown—just the JSON object.
  • Ensure the JSON parses and matches the quiz schema (optional answers allowed, but included where specified above).
  1. Acceptance checks (self-test before returning)
  • Freeform share is 16–22% of total questions (≥1 per section if feasible).
  • All scale items include anchor answers with value: “0” and value: “10” (scores depend on question direction).
  • All boolean answers begin with “Yes”/“No” and use commas for any continuation.
  • No question mixes verbs between prompt and answers (e.g., handle vs manage).
  • No compound constructs left unsplit where it matters.
  • Scoring monotonic and aligned with positive behavior/status.
  1. Branching logic (filterQuestion / filterValues / autoFill)

Critical rules:

a) Only freeform questions may have autoFill. Boolean, scale, and MC questions must never have autoFill. b) Filtered questions must immediately follow their gate question. A boolean gate and its dependent freeform must be adjacent — no other questions between them. This overrides the general “booleans before freeforms” ordering guideline (Rule 7). c) filterValues: [] (empty array) means “skip if the filter question has any value at all.” This is used for back-fill — when a freeform already has a stored value, its boolean gate can be skipped entirely.

autoFill values:

  • null = no auto-fill.
  • "quiz" = from a previous quiz result for the same question handle.
  • "" (empty string) = from factoid memory using the question text as the lookup key.
  • Any other string = from factoid memory using that string as the lookup key.

How skipping works:

  • When a question is skipped, it is answered with the maxScore without being displayed.
  • For freeform questions the max-score answer is "N/A".

Pattern A: Boolean → freeform with auto-fill (full back-fill pattern)

{
  "handle": "have_medical_conditions",
  "type": "boolean",
  "question": "Do you have any chronic medical conditions diagnosed by a healthcare professional?",
  "filterQuestion": "describe_medical_conditions",
  "filterValues": [],
  "maxScore": 7,
  "weight": 5,
  "answers": [
    { "label": "Yes", "value": "Y", "score": 1 },
    { "label": "No", "value": "N", "score": 7 }
  ]
},
{
  "handle": "describe_medical_conditions",
  "type": "freeform",
  "question": "Please describe your chronic medical conditions and how they affect your daily life.",
  "filterQuestion": "have_medical_conditions",
  "filterValues": ["N"],
  "autoFill": "",
  "maxScore": 10,
  "weight": 5
}

Flow:

  1. If factoid memory has a stored description → the freeform has a value → the boolean’s filterValues: [] triggers → boolean is skipped (back-filled as “Y”) → freeform is shown pre-filled for confirmation.
  2. If no stored value → boolean is asked → if “No”, freeform is skipped (auto-filled at maxScore with “N/A”) → if “Yes”, freeform is shown.

Pattern B: Boolean → freeform without auto-fill (simple skip)

{
  "handle": "track_health_metrics",
  "type": "boolean",
  "question": "Do you track health metrics (activity, sleep, etc.)?",
  "maxScore": 7,
  "weight": 2,
  "answers": [
    { "label": "Yes", "value": "Y", "score": 7 },
    { "label": "No", "value": "N", "score": 1 }
  ]
},
{
  "handle": "list_tracking_methods",
  "type": "freeform",
  "question": "Please list all wearables, apps, and other tracking methods that you use.",
  "filterQuestion": "track_health_metrics",
  "filterValues": ["N"],
  "maxScore": 10,
  "weight": 2
}

No back-fill — boolean is always asked. If “No”, freeform is skipped.

  1. Values vs. state questions
  • A state question measures how someone is doing (e.g., “How fulfilled do you feel by your community connections?”). A values question measures what someone cares about (e.g., “How important is community to you?”).
  • Quizzes should primarily ask state questions. Values questions are acceptable only as filter gates — they determine which follow-up questions are relevant, but should not heavily penalize respondents whose values differ.
  • When a values question scores low, use branching logic to skip dependent questions and auto-fill them at a neutral-to-positive score. For scale values questions, use filterValues with the low-end values (e.g., ["0","1","2","3"] for ≤3 on a 0–10 scale). This prevents the quiz from penalizing legitimate lifestyle choices.

AI verification

After creating or updating a quiz, or when asked to evaluate one, use these criteria:

  • Relevance: Are the questions relevant to scoring the given life domain?
  • Clarity: Are the questions and answers easy to understand and respond to?
  • Uniqueness: Does each question surface new information, or is it just repetitive?
  • Coverage: Do the questions for a given domain cover the whole range of the domain?
  • Accuracy: Are the questions and answers factual and evidence-based (when applicable)?
  • Correctness: Does the quiz pass programmatic verification

Programmatic verification

  • Run uvilo_quiz_qc.ts on each domain file to verify its accuracy
  • Quick start
    • run with tsx from Shared drives/Uvilo/Content/Taxonomy System/Scripts
    • npx tsx uvilo_quiz_qc.ts path/to/quiz.json
    • optional fixes: npx tsx uvilo_quiz_qc.ts —autofix-typography —write path/to/quiz.json
    • with schema: npx tsx uvilo_quiz_qc.ts —schema ./UploadQuizSchema.ts path/to/quiz.json
    • multiple files: npx tsx uvilo_quiz_qc.ts path/to/*.json (enables cross-file duplicate handle detection)
  • What it checks:
    • ~20% freeform (16–22%) and ideally ≥1 freeform per section
    • Max 40 questions per quiz
    • 0/10 anchors for all scales (supports inverted scores for negative questions)
    • Boolean labels start with Yes/No and use a comma for continuation
    • Boolean scoring direction heuristic (no inversions)
    • Monotonic multiple-choice scoring
    • Verb consistency (handle vs manage, etc.)
    • Smart apostrophes (flags straight ones; can autofix)
    • Compound prompts (suggests splitting)
    • Ordering: booleans before broad freeform
    • Handle validation: 3–32 chars, unique within and across files
    • Slug-version consistency
    • Weight and maxScore bounds (configurable)
    • Branching logic: autoFill only on freeform, filterQuestion targets exist, filter adjacency