Recommended playsets — build spec
Founder ruling (2026-09-01 iMessage): "Games are our unit. Playsets are generated on demand. We could add premade recommended playsets that we roll up for parents. Particular themes, particular skills focus, etc." Replaces pack pages as the curated-collection surface (queue rulings block; R1 retires /packs/ as browsing).
One sentence: a recommended playset is 6 curated game slugs plus a parent-facing blurb, stored as a flat file in the repo, rendered as cards on Home and Browse, and tapping one seeds the existing playset-builder tray pre-filled — from where the parent can swap games and download the same 7-page PDF (title page + 6 games) the builder already produces.
1. Data shape
New file: src/data/recommended-playsets.yaml (flat file in git, no database — tier-1 rule "adding one is premature" holds; this is catalog metadata exactly like meta.yaml).
version: 1
playsets:
- slug: back-to-school # stable ID; URL-safe; never renamed, only retired
title: "First Day of School"
kind: theme # theme | skill — which roll-up axis this set sells
blurb: >- # parent-facing, 2-3 sentences: what's inside and
... # what the child practices. The §3 title-page test
# applies: if this can't be written without
# hand-waving, the set doesn't ship.
tags:
themes: [everyday_life] # taxonomy theme keys (may be empty)
skills: [numbers_counting, writing_tracing, letters_phonics] # taxonomy skill keys
games: # EXACTLY 6 slugs, order = print order
- count-school-supplies
- trace-abc
- first-sounds
- star-dot-to-dot
- trace-the-shapes
- build-the-word
status: live # draft | live — draft renders nowhere
created: '2026-09-01'
Build-time validation (extend scripts/validate-taxonomy.mjs or a sibling validate-playsets.mjs, wired into the same prebuild):
- exactly 6 games; every slug exists under
content/games/; every referenced game hasstatus: liveANDhasPrintable(slug)true — a playset pointing at a pending-review or PDF-less game fails the build, same fail-loud posture as unknown taxonomy keys tags.themes/tags.skillsvalues must be keys insrc/data/taxonomy.yaml(no new vocabulary through the side door)- playset slugs unique;
kindin the closed pair - honesty check (cheap, mechanical): every
tags.skillsentry must appear asskillorskill_secondaryon at least one of the 6 games; everytags.themesentry on at least one game'sthemelist. The card cannot claim a focus the games don't carry.
Loader: loadRecommendedPlaysets() in src/lib/games.js (or a small playsets-recommended.js — do NOT touch the retiring packs.js), joining each slug to its full game record so cards render titles/previews without duplication.
2. Where they surface
- Home: a "Recommended playsets" row replaces the retired packs section as the curated shelf (pairs with queue R1). Card design is queue item R3 (design role, against DESIGN-scribble-works.md): title, kind badge (theme/skill), blurb, the 6 game thumbnails, one action — "Start with this playset." Cap the row at 4 cards; more scrolls or moves to Browse.
- Browse: a compact strip above the filter rail ("Not sure where to start?") showing the same cards small. Browse already hosts the tray, so seeding is same-page there.
- No detail pages. A
/playsets/<slug>page would recreate the pack pages the founder just retired. The card IS the surface; the builder is where you land. (Open question 5 if the founder wants shareable URLs.)
3. Seeding the builder
Tap → the existing tray (src/scripts/playset.js, sw.playset.v1 localStorage state) is pre-filled with the 6 slugs and the playset title as the tray name.
- Add
seedPlayset(slugs, name)toplayset.js: writes state via the existing guardedsaveState, works in the in-memory fallback when storage is blocked. - Card button carries
data-playset-seed+ a JSON payload (slugs + name) rendered at build time — no fetch, no runtime lookup. - Non-empty-tray guard: if the tray already holds games, confirm before replacing ("Replace your current playset?"). Never silently destroy a half-built set.
- From Home: Home currently has no tray (queue item 21 left that as a founder call). Seeding from Home writes state then navigates to
/browsewhere the tray renders it. If the founder later puts a tray on Home, the navigate drops out — the seed function is surface-agnostic either way. - Download path: unchanged. The seeded tray uses the same 7-page assembly (title page + 6 games) from PR #4; the playset TITLE PAGE template (queue item 2) serves recommended and hand-built sets identically — the title page for a recommended set can reuse the curated blurb as its parent-facing writeup.
4. Relation to on-demand playsets and the magic wand (item 19)
Three rungs of the same tray, no duplicated machinery:
| Surface | What fills the tray | Mechanism |
|---|---|---|
| Hand-built (shipped, PR #4) | Parent picks 6 games | Browse + tray |
| Recommended (this spec) | Editor curation, static data | Flat file → seed the tray |
| Magic wand (item 19) | Curriculum-aware auto-fill of EMPTY slots (age band + skill balance + kid's interests) | Gen-AI, runtime |
Recommended playsets are deterministic curation, zero gen-AI, zero credits — the trust-ladder rung below the wand (manual → Customize → wand). They compose rather than compete: seed a recommended set, remove two games, and the wand refills the holes. The wand spec should treat a seeded recommended set as ordinary tray state — nothing here needs to know the wand exists. (Later, curated sets are natural few-shot exemplars for the wand's balance logic — note for item 19's spec, not scope here.)
5. Authoring workflow
- Author: product role (charter §2 — choosing activities and splitting catalog surfaces is product's autonomous lane). Product writes/edits
recommended-playsets.yamlin overnight rounds; seasonal calendar is a standing input (back-to-school NOW, Halloween next). - Gates before
status: live:- Mechanical: prebuild validator (§1) — free, catches slug/tag/count errors.
- Fresh-eyes blurb critic (per-dispatch subagent, zero context): does the blurb honestly describe these 6 games' taxonomy without over-claiming pedagogy? This is the charter's §3 test applied per-set: a set whose blurb needs hand-waving fails and goes back to the queue.
design-criticon the rendered Home/Browse cards (R3 build, once per template — not per playset).
- Ship cadence: playset additions are ordinary overnight-round artifacts (within the 4-per-round §8c budget); editing the YAML + passing gates + PR/preview, production deploy on the normal production-time rail.
- Retirement: seasonal sets flip
status: draftafter their window (product's call); the file keeps them for next year.
6. Launch candidates (real slugs, 14-game catalog as of 2026-09-01)
- First Day of School (theme) —
count-school-supplies,trace-abc,first-sounds,star-dot-to-dot,trace-the-shapes,build-the-word. Seasonal NOW. Blocked oncount-school-suppliesclearing pending-review (PR #8); validator will hold it until then — correct behavior, not a bug. - Primeros Pasos — bilingual reading (skill) —
sonido-inicial,silabas-de-m,construye-la-palabra,une-la-palabra,first-sounds,word-and-picture. All 4 Spanish games plus two English mirrors. The true pairs are sonido-inicial/first-sounds and une-la-palabra/word-and-picture; silabas-de-m has no English mirror and construye-la-palabra's mirror (build-the-word) is not in this set, so the blurb sells the two real pairs, not blanket mirroring (the §5 blurb-honesty gate will hold it to that). Multilingual as engine property, not Spanish positioning. - Learning to Read (skill: letters_phonics + reading_words, EN) —
first-sounds,trace-abc,build-the-word,word-and-picture,trace-the-shapes,star-dot-to-dot. First 4 are the spine; last 2 are labeled stretch picks (pencil control + counting breather between reading games), and the blurb must say so honestly. - Pencil Ready — fine motor (skill: writing_tracing + scissors_motor_skills) —
trace-abc,trace-the-shapes,star-dot-to-dot,bunnys-snack-maze,color-the-dino,count-school-supplies(traces the number; same pending-review dependency, swapwho-eats-whatif launching before it clears). Note:color-the-dinocarries neither claimed skill tag; it rides as an art/coloring breather, and the set's claimed tags stay validator-true because the honesty check requires each tag on at least one game, not on all six. - Rainy-Day Low-Ink (practical roll-up) —
bunnys-snack-maze,color-the-dino,star-dot-to-dot,trace-abc,trace-the-shapes,who-eats-what. Exactly the 6low_inkgames in the catalog: a real parent problem (printer ink) the flags facet was built for. Note:kindis neither theme nor skill; either allowkind: practicalor drop this set (open question 3).
Sets the catalog CANNOT roll yet (a finding, not a failure): a numbers-focus set (only 2 numbers_counting games) and an animals theme set (only 3 animals/creature games). The recommended-playsets surface doubles as a gap detector for the P1 new-game lane: product should bias upcoming game picks toward completing the nearest unrollable set. That loop, curation demand pulling game production, is the cheapest version of the charter's named queue-prioritization gap.
7. Open questions for the founder
- Language facet. Taxonomy has no
languagefacet (facet count frozen at 5, founder-locked). The bilingual set works by hand-curation, but Browse can't filter Spanish and the validator can't check language claims. Addlanguageas facet 6 (founder decision by the freeze rule), or leave language as engine-property-only? - Home card cap — is 4 recommended sets on Home right, and do seasonal sets always take slot 1?
- Is
kind: practicalallowed (the low-ink set), or do recommended sets stay strictly theme/skill per the ruling's wording? - Shareable playset URLs — seed-only (this spec's default, avoids recreating pack pages), or does a recommended set deserve a stable URL for sharing/SEO? Growth may want the latter eventually; deferrable.
- Gap-driven game picks — greenlight product biasing the P1 lane toward completing the numbers and animals sets?
Build order
R2 (this spec) → R3 design round (card/row) + §1 data file & validator + §3 seed function in one engineering round → launch candidates 2, 3, 5 immediately; 1 and 4 when count-school-supplies goes live.
Related
- [[2026-08-31-studio-charter]] — §2 roles, §3 parent-overview page (the blurb inherits its test), §6 account model
- [[2026-08-31-marketplace-taxonomy-proposal]] — locked facets
- Queue:
~/.claude/state/studio/queue.mdR1/R2/R3, items 2 (title page), 19 (magic wand), 21 (Home tray), P1 (new-game lane) - Code:
~/Projects/scribble-works/src/lib/games.js·src/scripts/playset.js·src/pages/{index,browse}.astro