Browser-playable multilingual quizzes from a verified English bank, AI used only to translate + to craft quizzes via a chat-bubble wizard.

1. πŸ“œ /ymlsum

project:     QuizWizz πŸ§™
type:        WordPress plugin (FOSS, GPLv2+)
one_liner:   Browser-playable multilingual quizzes from a verified English bank,
             AI used only to translate + to craft quizzes via a chat-bubble wizard.
platform:    {wp: "7.0 Armstrong", php: "8.5 (min 8.3)", db: "MySQL/MariaDB", react: 18}
 
principle:   DATASET-IS-TRUTH β–Έ no fact-generation. AI scope = {batch_translate, chat_craft} only.
 
data_model:                                # native, no bloat
  cpts:      [quiz, question]              # custom post types
  taxes:     [subject, difficulty, language, tag]
  store:     question{stem, type, choices[], correct_idx, explanation, src, lang}
  note:      Uses PDO SQLite database (opentdb.sqlite) instead of wp_remote_get for zero-latency lookups
 
quiz_sources:
  primary:   OpenTDB (Bundled local SQLite DB, ultra-fast ORDER BY RANDOM() LIMIT, pre-translated swarm localization)
  big_bank:  TriviaQA (~95k)    # volume, human-authored, CC BY 4.0 (open-answer→1× distractor prep)
  academic:  Global-MMLU        # 42 langs PRE-translated, 57 subjects (skip translation!)
 
ai:
  gateway:   OpenRouter         # OpenAI-compatible /chat/completions, SSE streaming
  picker:    GET /api/v1/models?order=newest  # cache+refresh hourly β†’ model dropdown
  selectable:[model, prompt]    # both user-editable, every call
  cost_ctrl: [":floor variant", "max_tokens cap", "BYOK", spend-limit]
  jobs:
    translate: batch job (WP-Cron) β†’ store per-language question sets
    agent:     "Magical Quiz Wizz" floating chat bubble β†’ NL input β†’ quiz draft
  json:      response_format=json_schema  # reliable question objects
  key:       server-side only (wp-config/env) β€” NEVER client JS
 
play:                            # "on location, simply in browser"
  engine:    Alpine.js (~7kB, no build) renders + grades client-side
  data:      quiz JSON localized via wp_localize_script / REST
  resume:    localStorage (real plugin only; not in WP artifacts)
  modes:     [practice, timed, shuffle, Form-A/B/C]
 
output:
  print:     window.print() + @media print CSS  # zero-dep results sheet + answer key
  pdf_srv:   mPDF 8.3.1 (optional, for saved/emailed/non-Latin)
  share:     Web Share API (navigator.share) + Open Graph meta
 
admin:                           # most-genius WP 7.0 backend
  ui:        Data Views (filter/sort quizzes & questions, native 7.0)
  ability:   register quiz-gen as a WP Abilities API ability (plugs into 7.0 AI hub)
  settings:  @wordpress/components React page β†’ /wp/v2/settings (show_in_rest)
  block:     dynamic block apiVersion 3 (embed quiz on any page)
 
security:    [cap_check β†’ nonce β†’ sanitize β†’ ESCAPE, $wpdb->prepare(%s %d %i),
              "defined('ABSPATH')||exit", permission_callback on EVERY route,
              sanitize HTML before mPDF]
qa:          [Plugin Check (mandatory), PHPCS+WPCS, PHPUnit, 2FA on wp.org acct]
i18n:        __()/esc_html__() + .pot
 
milestones:
  m1: CPT + OpenTDB import + Alpine browser play + print sheet     # playable MVP
  m2: OpenRouter model-picker + batch translate + Data Views admin # multilingual + backend
  m3: "Magical Quiz Wizz" chat-bubble agent (NL→quiz) + share      # the magic
  m4: security pass + Plugin Check green β†’ package/ship
 
non_goals:   [LMS/courses, payments, per-user accounts (v1), server-side grading]
foss_purity: OpenRouter = the ONLY SaaS dep; swap for LibreTranslate + Ollama/vLLM = 100% self-host
risks:       [MT loses culture→spot-check, distractor drift→re-validate,
              mPDF dated CSS→use print/headless-chrome, SSE buffering→non-stream fallback]

2. πŸš€ Rollout

PhaseBuildβœ… Done when
βœ… 1 MVPCPT + OpenTDB import + Alpine play + print sheetquiz is playable & printable
βœ… 2 Multimodel picker + batch translate + Data Views adminquiz works in N languages
[ ] 3 MagicπŸ§™ chat-bubble wizard (NLβ†’quiz) + sharepromptβ†’quiz in one chat
[ ] 4 Shipsecurity pass + Plugin Check greenzero errors β†’ package

3. πŸ” YAGNI Loop

Copy-paste, point at any builder piece (form/route/admin/code), run until it self-certifies. Philosophy: perfection = 0 defects on required scope + 0 unrequired scope. Adding is easier than fixing, so cut first, then polish.

ROLE: Ruthless senior reviewer. MANDATE: make it perfectly do EXACTLY what the SPEC needs β€” nothing more.
 
SPEC (the only thing that matters):
  User picks {category(ies), count, difficulty, mode ∈ {online, print}, language}
  β†’ a correct, valid quiz is produced, every time, on every edge case.
 
ARTIFACT UNDER REVIEW: <paste code / component / route / admin feature>
 
──────────────── THE LOOP (repeat each pass) ────────────────
1. βœ‚οΈ YAGNI SWEEP β€” for every field/feature/branch/dependency/abstraction:
     ask 3: (a) Required by SPEC *now*? (b) Does removing it break SPEC? (c) Cheaper to add later than carry now?
     β†’ if NOT-required & doesn't-break & cheaper-later β‡’ CUT IT (log as βœ‚οΈ). List all cuts first.
2. πŸ” SCAN the 8 LENSES β€” log EVERY issue found.
3. 🏷️ CLASSIFY each by severity (rubric below).
4. πŸ”§ FIX only the highest-severity batch β€” one concern at a time, smallest change.
5. βœ… VERIFY the fix + scan for regressions it introduced.
6. ↻ RE-RUN from step 1 on the changed artifact.
 
EXIT (stop, do NOT gold-plate) when ALL true:
  β€’ 0 P0 and 0 P1 issues
  β€’ YAGNI sweep finds nothing left to cut
  β€’ every SPEC acceptance test passes (incl. edge cases)
 
──────────────── 8 LENSES ────────────────
βœ… Correctness  edge cases: 0 results Β· count > pool Β· empty category Β· all-difficulties Β· mixed split Β· RTL/non-Latin lang Β· mode switch mid-build
πŸ”’ Security     capβ†’nonceβ†’sanitizeβ†’escape Β· count clamped SERVER-side Β· key never client-side Β· $wpdb->prepare(%s %d %i)
β™Ώ A11y         keyboard-only Β· ARIA roles/labels Β· focus mgmt Β· contrast
πŸ“± UX           states present (empty/loading/error/success) Β· mobile Β· one obvious action
⚑ Perf         no N+1 · pool-count & model-list cached · minimal payload
🧩 Simplicity   fewest moving parts Β· no dead code Β· no unused deps Β· no premature abstraction  ← YAGNI lives here
🌍 i18n         strings wrapped · translated data renders · fonts load
🚒 Ship         Plugin Check · WPCS · clear names · docblocks on public API
 
──────────────── SEVERITY ────────────────
P0 broken / insecure / data-loss      β†’ fix immediately
P1 wrong on an edge case / SPEC gap   β†’ fix this pass
P2 UX / perf friction                 β†’ fix if cheap
P3 cosmetic polish                    β†’ fix only if free
 
──────────────── OUTPUT EACH PASS ────────────────
1) βœ‚οΈ CUTS: bullet list of everything removed/deferred + why
2) ISSUE TABLE:  | # | Lens | Sev | Issue | Fix / βœ‚οΈCUT |
3) REVISED ARTIFACT: the diff (changed lines only)
4) VERDICT:  πŸ” LOOP AGAIN  |  βœ… PERFECT (SPEC met Β· nothing to cut Β· all tests green)

Contents

1 item under this folder.