diff --git a/seed/questions/DAILY_SINGLE_CHOICE_WEEKDAY_SYSTEM.md b/seed/questions/DAILY_SINGLE_CHOICE_WEEKDAY_SYSTEM.md index f8e12689..d82c6c3c 100644 --- a/seed/questions/DAILY_SINGLE_CHOICE_WEEKDAY_SYSTEM.md +++ b/seed/questions/DAILY_SINGLE_CHOICE_WEEKDAY_SYSTEM.md @@ -30,13 +30,23 @@ Use the old file name only while the app code still expects it. The content insi This special daily pack uses: -* 500 total questions -* 75 free questions -* 425 premium questions +**Weekday pack (frozen — do not change these 500):** + +* 500 total weekday questions +* 75 free weekday questions +* 425 premium weekday questions * 500 single_choice questions * 4 options per question preferred * 4 to 6 options allowed +**Wildcard add-on (new — see the Wildcard Mode section):** + +* 11 free single_choice wildcard questions (free only; pool size must stay coprime with 10) + +**New pack totals with the wildcard add-on:** + +* 511 total · 86 free · 425 premium · 511 single_choice + Do not apply the standard 250 question category mix to this pack. ## Required Type @@ -579,16 +589,23 @@ quick, warm, PG-13 max on the free tier, 4 options preferred (4–6 allowed), si ### Wildcard counts -* **12 free** `single_choice` wildcard questions. **Free only** — the daily picker never draws from +* **11 free** `single_choice` wildcard questions. **Free only** — the daily picker never draws from the premium pool, so premium wildcards would never be served. Do not author premium wildcards. -* This is **in addition** to the existing 500 (75 free + 425 premium) weekday questions. +* Added on top of the existing 500 weekday questions → new pack totals **511 total · 86 free · + 425 premium** (the "Required Counts" section above is updated to match). +* **Why 11, not 10 — this is a correctness constraint, not a preference.** Wildcard days fall ~10 + days apart (day-of-year mod 10 == 3) and the picker indexes `epochDay % poolSize`. A pool size that + shares a factor with 10 (i.e. divisible by 2 or 5 — e.g. 10 or 12) collapses the rotation, so only + a fraction of the questions ever appear in a given year. **The wildcard pool size must be coprime + with 10** (9, 11, 13, …). 11 gives full rotation with good freshness — do not round it to 10. ### Wildcard IDs -Continue the existing sequence so ids stay sortable and unique — the picker sorts by id: +Continue the existing sequence so ids stay sortable and unique — the picker sorts by id (the pack +currently ends at `_500`, no gaps): ```text -daily_single_choice_weekly_v1_501 … daily_single_choice_weekly_v1_512 +daily_single_choice_weekly_v1_501 … daily_single_choice_weekly_v1_511 ``` ### Wildcard tags (EXACT — this is an app contract) @@ -641,11 +658,22 @@ weekday `mode_*` tag (a weekday mode tag would wrongly pull the wildcard into th } ``` +### Wildcard authoring rules (easy-to-miss) + +* These 11 are **net-new** questions, not a patch. "Patch Discipline: Fix Only What Fails" freezes the + existing 500 — it does not stop you creating the new wildcard set. Do not renumber or edit any 001–500. +* `options` must be **mirrored exactly** into `answer_config.options` (same ids, same text, same order) + with `"selection_style": "single"` — the app reads the options from `answer_config`. +* Option `id`s are lower_snake_case and **unique within the question**. +* `access` is `"free"` for all 11 (there is no premium wildcard). +* Field schema, types, and validation rules live in `QUESTION_SCHEMA.md`; tone/voice gates live above in + this guide (Daily Fun Gate, Option Quality Standard, Banned Tone Words). Wildcard is held to the same bar. + ### After the JSON is authored — engineer rollout (NOT the content agent's job) -Once the 12 wildcard questions are in `daily_fun_multiple_choice_v3.json`, an engineer lands them: +Once the 11 wildcard questions are in `daily_fun_multiple_choice_v3.json`, an engineer lands them: -1. **Asset DB:** insert the 12 rows into `app/src/main/assets/database/app.db` `question` table +1. **Asset DB:** insert the 11 rows into `app/src/main/assets/database/app.db` `question` table **data-only** (`category_id='daily_fun_mc'`, `status='active'`, `is_premium=0`, `tags` containing `mode_wildcard`). **Do NOT run `build_db.py`** — a full rebuild changes the Room identity hash and breaks the shipped DB (see project notes). Data-only inserts are safe. @@ -796,14 +824,14 @@ These sources informed the daily fun rules. Do not copy their question lists. Us Before shipping: -1. Run schema and count validation. +1. Run schema and count validation against the totals in Required Counts (511 · 86 free · 425 premium once the wildcard add-on is in; 511 single_choice). 2. Run duplicate question checks. 3. Run duplicate option-list checks. 4. Check repeated openers and repeated option text. -5. Read 10 random questions from each weekday. -6. Mark anything therapy-coded, boring, weird, logistical, or not fun. +5. Read 10 random questions from each weekday, plus all 11 wildcard questions. +6. Mark anything therapy-coded, boring, weird, logistical, or not fun. For wildcard specifically, also mark anything tied to a particular weekday/day-name (wildcard must read on any day). 7. Fix the marked items. -8. Run a second random sample from each weekday. +8. Run a second random sample from each weekday, and re-read the wildcard set. 9. Fix only the newly marked sample items. 10. Run the second sample again if any sampled item changed. 11. Ship only when the second sample passes cleanly and the remaining hard flag count is 0. diff --git a/seed/questions/QUESTION_SCHEMA.md b/seed/questions/QUESTION_SCHEMA.md index bd272c67..30341d50 100644 --- a/seed/questions/QUESTION_SCHEMA.md +++ b/seed/questions/QUESTION_SCHEMA.md @@ -180,15 +180,24 @@ Compatibility file name: daily_fun_multiple_choice_v3.json ``` -Target counts: +Target counts — weekday pack (frozen; do not change these 500): | Field | Count | |---|---:| -| total | 500 | -| free | 75 | -| premium | 425 | +| weekday total | 500 | +| weekday free | 75 | +| weekday premium | 425 | | single_choice | 500 | +Plus the wildcard add-on (surprise days; see `DAILY_SINGLE_CHOICE_WEEKDAY_SYSTEM.md` → Wildcard Mode). +The wildcard pool size must stay **coprime with 10** (the wildcard-day spacing), so 11, not 10/12: + +| Field | Count | +|---|---:| +| wildcard free | 11 | + +**New pack totals (weekday + wildcard):** 511 total · 86 free · 425 premium · 511 single_choice. + These counts do not apply to standard category packs. ## Daily Pack Metadata Example @@ -198,9 +207,9 @@ These counts do not apply to standard category packs. "id": "daily_single_choice_weekly_v1", "title": "Daily Single Choice", "access": "mixed", - "description": "One weekday themed single choice question per day.", - "count": 500, - "free_count": 75, + "description": "One weekday themed single choice question per day, plus wildcard surprise days.", + "count": 511, + "free_count": 86, "premium_count": 425, "question_type_policy": "single_choice_only", "review_policy": "weekday_batch_loop_required",