← Back to index | ← 02 Tenancy model | 04 Config schema →
The five canonical Money Quiz formats, their IDs, slugs, URLs, aliases, scoring paths, and how to add a new one. Reflects the post-rename state as of 2026-05-18 (C-phase complete).
The five canonical formats
| Canonical ID | Display name | Bare slug | What it is | Scoring engine |
|---|---|---|---|---|
likert | Money Quiz | quiz | 112-trait Likert questionnaire on Ilana's WordPress | WP PHP → gateway /calibrate |
qa | Money Mirror | mirror | Q&A conversation with adaptive question selection | TS analyseScores |
game | Money Game | game | 6-round card-flip game | TS analyseScores (gameMode) |
deal | Money Deal | deal | 78-card archetype-revealing card game | Agent generate_results |
realm | Money Realm | realm | Visual / mystical variation of Deal | Agent generate_results (shares Deal engine) |
Where each format is served
┌─────────────────────────────────────────────┐
│ Platform host: quiz.thesynergygroup.ch │
│ (Next.js moneyquiz-app pod) │
│ │
│ / → Money Mirror (qa) │
│ /mirror → re-export of / │
│ /quiz → tenant-router │
│ /game → Money Game │
│ /deal → Money Deal │
│ /realm → Money Realm │
│ /chooser → 5-card selection page │
└─────────────────────────────────────────────┘
▲
│ iframe with ?tenant=mmc
│
┌─────────┴────────────────────────────────────┐
│ MMC host: mindfulmoneycoaching.online │
│ (WordPress) │
│ │
│ /money-quiz/ → NATIVE WP page (Likert) │
│ /money-mirror/ → iframe (Mirror) │
│ /money-game/ → iframe (Game) │
│ /money-deal/ → iframe (Deal) │
│ /money-realm/ → iframe (Realm) │
└───────────────────────────────────────────────┘
The four iframe pages are auto-created by mmc-moneyquiz-bridge/auto-pages.php on admin_init (idempotent via option flag). WordPress post IDs 21692–21695.
The /money-quiz/ Likert page is a native WordPress page (not an iframe) — it has its own theme template at page-money-quiz.php and JS engine at traditional-quiz-engine.js. After the user completes the 112 questions, the JS POSTs scores to /wp-json/sg-course/v1/archetype-scores, which then calls the gateway's /calibrate endpoint before writing to mq_* tables. See 09 MMC bridge.
Alias map
The platform accepts both new (canonical) and legacy IDs at every system boundary. Aliases live in api-gateway/registry/assessment.py::FORMAT_ALIASES and Personas/_format_aliases.py.
| Legacy id | Canonical id | Where it lingered |
|---|---|---|
quiz | qa | Pre-rename name for Q&A format |
traditional | likert | Pre-rename name for the 112-Likert format |
qa_quiz | qa | Persona dev script naming |
mq-conversation | qa | Older MMC marketing naming |
mq-likert | likert | Older MMC marketing naming |
mq-binary | likert | A/B variant naming in MMC GA4 events |
The normalize_format_id() function in assessment.py is the single normalization point. Every system boundary that reads a format id should call it.
URL composition
Every tenant's per-format URLs are composed by compose_tenant_urls() (Python, gateway) and mirrored in the dashboard preview by composePreview(). See 02 Tenancy model §Per-tenant URLs for the rule.
The composed map appears in /resolved responses as _tenant_urls:
{
"_tenant_urls": {
"likert": "https://mindfulmoneycoaching.online/money-quiz/",
"qa": "https://mindfulmoneycoaching.online/money-mirror/",
"game": "https://mindfulmoneycoaching.online/money-game/",
"deal": "https://mindfulmoneycoaching.online/money-deal/",
"realm": "https://mindfulmoneycoaching.online/money-realm/"
}
}
Note: _tenant_urls.likert comes from tenant_brand.canonical_quiz_url (a separate field), NOT from URL composition with the platform default. This is because the Likert path is fully tenant-controlled — every tenant decides where it hosts the WP plugin.
How a quiz session knows which format it is
Three places where the format id matters:
-
Public quiz route: each format has a dedicated route in moneyquiz-app/src/app/ —
mirror/page.tsx,game/page.tsx,deal/page.tsx,realm/page.tsx. The route itself is the format selector. -
Agent session: a session row in Redis stores
framework_name+ aformatfield that distinguishesqafromgame(both go throughquiz_engine). Set whenstart_quiz(or its aliasstart_qa) action is invoked. -
Webhook payload: the
sourceandresponse_formatfields in the archetype-scores webhook payload distinguish format on the receiver side:{"source": "money-mirror", "response_format": "qa"} {"source": "money-game", "response_format": "game"} {"source": "the-deal", "response_format": "deal"}
The MMC receiver writes response_format to the mq_taken.Response_Format column so Quiz Leads can filter by format.
Scoring path per format
Each format has a different scoring path, but all five apply the same Tier-2 calibration rules as of 2026-05-19. See 06 Scoring + calibration for the full engine.
| Format | Player flow | Score derivation | Calibration applied at |
|---|---|---|---|
likert | WP page with 112 Likert questions | JS sums weighted trait values per archetype | Gateway /calibrate (via WP receiver) |
qa | Adaptive Q&A, ~7 questions, picks from a bank of ~30 | Agent process_answer updates session scores; final scores POSTed to /api/quiz/results | TS analyseScores |
game | 6 rounds, ~36 interactions, fast | Game session accumulates per-archetype scores during play | TS analyseScores |
deal | Card-game UX, ~60 cards | Agent NATS session; generate_results returns final scores + narrative | Agent generate_results (Python) |
realm | Visual variation of Deal | Same as Deal | Same as Deal |
Adding a new format
Order of operations (mirrors the C-phase pattern — alias layer first):
- Choose a canonical id (short lowercase, e.g.
wheel). - Add to the framework JSON under
dimensions(if it has new dimensions) ormodes(if it's a new way of asking the same questions). - Add a slug entry to
FORMAT_BARE_SLUGSin both framework_config.py and the dashboard preview at brand/page.tsx. Use the same{id, slug, display}shape. - If it has wire-level NATS interactions, register actions in the agent (e.g.
start_wheel) and add aliases toFORMAT_ALIASES. - Add the public route at
moneyquiz-app/src/app/<slug>/page.tsx. Wire the format-specific UI. - Add a dashboard mode editor at
dashboard/src/app/[locale]/assessments/[framework]/modes/<slug>/page.tsx. Pattern aftermodes/quiz/page.tsx(Money Quiz Likert editor). - Update the MODES array in
modes/page.tsxhub. - Add to MMC auto-pages if tenant-hosted iframes are needed: extend
MMC_BRIDGE_AUTO_PAGESin auto-pages.php. - Update this section with the new format.
Don't skip the alias layer if you're renaming an existing format. See feedback_alias_first_multi_phase_rename.md for the methodology.
History
| Date | Phase | Change |
|---|---|---|
| 2026-05-17 | (pre-rename) | Format names were a mix: Legacy Quiz / Q&A Quiz / The Game / The Realm |
| 2026-05-18 C1 | Aliases | Gateway accepts qa, likert, mq-mirror, mq-quiz alongside legacy ids. Idempotent rollout. |
| 2026-05-18 C2 | Routes + schema | TSG routes added (/chooser, /mirror, /realm, /quiz); MMC auto-pages mu-plugin created (/money-mirror/, /money-game/, /money-deal/, /money-realm/). Migration 0008 adds tenant_brand.slug_prefix. |
| 2026-05-18 C3 | Personas dev scripts | qa_quiz → qa in test harness. |
| 2026-05-18 C4 | Dashboard editor folders | modes/quiz/ (was QA editor) → modes/mirror/; modes/likert/ (was 112-trait) → modes/quiz/. 308 redirect added. |
| 2026-05-18 C5 | URL composer | compose_tenant_urls() ships _tenant_urls map. |
| 2026-05-18 C6 | DB mode keys | TSG mode_overrides.quiz migrated to .qa, orphan quiz key dropped via direct SQL. Resolver _canonicalize_mode_keys() added. |
| 2026-05-18 C7 | NATS aliases | start_qa registered as alias for start_quiz. |
| 2026-05-18 C8 | In-product copy | "Share the Money Quiz" → "Share the Money Mirror" on booked page; GameBoard "The Money Game" → "Money Game". |
| 2026-05-18 C9 | File/dir cleanup | src/components/deal/realm/ → src/components/realm/. Dead app/deal/realm/page.tsx removed. |
| 2026-05-19 D | Webhook + calibration parity | Mirror/Game/Deal now POST to per-tenant CRM via tenant_brand.archetype_scores_webhook. Likert calibrated via gateway /calibrate bridge. |
Deferred: MMC theme traditional-quiz-engine.js → money-quiz-engine.js rename (touches live WP + 10+ refs).
Anti-patterns to avoid
- Hardcoding a format id literal anywhere outside of
FORMAT_BARE_SLUGS/FORMAT_ALIASES. Always go throughnormalize_format_id()orcanonicalize(). - Adding format names in i18n keys. Use generic keys like
modes.titlenotmodes.qa.title. Change "Money Mirror" by editing the value, not by renaming the key. - Forgetting the dashboard route → page.tsx mapping. Every sidebar nav
hrefmust have a matchingpage.tsx. See feedback_nextjs_dashboard_navvsroute.md. - Renaming WP / SEO-loaded paths to "match" canonical naming. SEO equity beats cosmetic consistency. Leave existing URLs frozen, document the mismatch.
Next
→ 04 Config schema — the 8 override columns, snapshots, and migrations.