feat: re-weight patron-saint quiz for multi-path discovery#210
feat: re-weight patron-saint quiz for multi-path discovery#210SimplyThomas wants to merge 4 commits into
Conversation
The quiz scored saints by weighted facet overlap with Intercession as the single highest weight (3) — yet Intercession is the sparsest facet (~18.6% of 2,740 saints), so the ~500 tagged saints crowded out the other ~81% even when those matched strongly on story or calling. That contradicts the multi-path discovery goal (CLAUDE.md §1/§10), where Intercession is the narrowest path and should not be over-indexed. Changes (src/lib/quiz.ts): - Re-weight toward the relatability paths: Story (experience) and Calling (vocation) lead at 3; Life (family), Region (origin), Virtue, and Intercession sit at 2; Tradition stays a light 1. Intercession drops from the dominant 3 to a meaningful mid weight. - Add a Region/Background dimension (origin, ~97% covered, previously unused) — "find a saint from my background" (§1). - Lead the question flow with Story rather than the affliction path. - Normalize per dimension: a matched dimension contributes its weight ONCE, so a sparse-but-high-weight facet can no longer dominate by stacking many tags. Breadth across dimensions wins; depth within one is a tie-break. Adds src/lib/quiz.test.ts (Vitest) locking in the weighting and asserting a story/calling match outranks an intercession-only match. No saint data changed.
Deploying orthodox-saints with
|
| Latest commit: |
492b361
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://5f0fd084.orthodox-saints.pages.dev |
| Branch Preview URL: | https://feat-quiz-reweighting.orthodox-saints.pages.dev |
The QUIZ config reweighting flows through the rendered flow automatically
(QuizForm.astro and quiz.client.ts iterate QUIZ), but the surrounding intro
and meta copy still foregrounded intercession ("lives and intercessions echo
your own"). Broaden it to the story/calling/background paths (§1) so the prose
matches the scoring.
|
Follow-up commit (5e9ebb9): aligned the quiz framing copy with the reweighting. The |
Previously the result panel led with the matched saint's full intercession
list ("Patron of …"), which could show patronage the seeker never selected and
hid the actual basis for the match. Replace it with a transparent, per-question
breakdown.
- quiz.ts: each match reason now carries its dimension ({ key, kicker, value })
instead of a bare value string, so the UI can group and label matches.
- quiz.client.ts: the result panel renders a "Why you were matched" block
listing, grouped by question (Your Story / Your Calling / Your Background / …),
the exact values the seeker picked that this saint shares. Companion cards gain
a compact shared-values line too.
- global.css: styling for the grouped match list and companion shared line.
- quiz.test.ts: lock the contract that reasons are tagged by question.
Verified in a built preview (Playwright): the block renders grouped rows and
companion shared lines. web-unit (19), web-lint, web-build all green.
|
Follow-up commit (22d98e1): result transparency. The result panel previously led with the matched saint's full intercession list ("Patron of …") — which could surface patronage the seeker never picked and hid the actual basis for the match. It now shows a "Why you were matched" block listing, grouped by question, the exact values the seeker selected that this saint shares (e.g. Your Story · Persecution · Torture / Your Calling · Writer / Your Background · Asia Minor). Companion cards gain a compact shared-values line too. Each match |
…ded 6 The quiz e2e walkthrough hard-coded `for (i = 1; i < 6; ...)` to advance through the question screens, assuming 6 questions. Adding the Region question made it 7, so the loop stopped one screen short and never clicked "Reveal my patron" — `.qz-patron` never appeared and the frontend gate failed. Derive the count from the rendered `.qz-step` screens so it survives question changes, and assert the new transparent "Why you were matched" block renders.
What & why
The patron-saint quiz (
src/lib/quiz.ts) scores saints by weighted controlled-vocab facet overlap. Its weights were misaligned with how complete the underlying data is — it weighted the sparsest facet highest:Because intercession was weighted highest but present for only ~18.6% of saints, the quiz systematically favored the ~500 intercession-tagged saints and gave the other ~81% little chance to surface — even when they matched strongly on story or calling. That contradicts the project's value model: per CLAUDE.md §1 the product is multi-path discovery (read/learn · share-a-name · relate to a story/life/vocation/background · need-matching), and §10 explicitly deprioritizes Intercessions as the narrowest path.
Coverage above was recomputed from the data, not taken on faith:
python build.pyfinder-coverage for the four fields it reports, and a direct non-empty-cell count ofdata/saints.csvfor Region of Origin / Family / Tradition (which it omits).Changes (
src/lib/quiz.ts)experience) and Calling (vocation) lead at 3; Life (family), Region (origin), Virtue, and Intercession sit at 2; Tradition stays a light 1.origin, ~97% covered, previously unused) — serves "find a saint from my background" (§1). Region was available inFinderSaintbut the quiz had no question for it.Tests
Adds
src/lib/quiz.test.ts(Vitest — there was none before). It locks in the weighting and asserts:Validation (all green)
make web-unit— 18 passed (10 new)make web-lint— cleanmake web-build—python build.py+astro buildboth exit 0 (2,768 pages)No saint data was changed — this is purely a scoring/weighting change.
Follow-up (out of scope, not bundled)
The finder's
OPEN_BY_DEFAULTfacet order insrc/lib/filter.tsopens Intercessions first — the same misalignment with the multi-path goal. Worth a separate small PR.Preview
https://feat-quiz-reweighting.orthodox-saints.pages.dev
(once the Cloudflare Pages check is green — previews render draft/flagged profiles)
🤖 Generated with Claude Code