From a7fb8e57398cc70f2473f49a4eceffe93c0d143b Mon Sep 17 00:00:00 2001 From: jay Date: Wed, 10 Jun 2026 17:34:44 -0400 Subject: [PATCH] Daily Word: grow the hopeful answer pool + lock it with a validation test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per Codex. Pool grown 51/44 → 115/104 hopeful answers (5/6 letter) via the agreed workflow: LLM proposes themed candidates → code filters to the bundled guess dictionary (length/alpha/dedup) → human spot-check prunes tone-drift ("growl", "plain", "color"…). ~3.5-month runway before repeats per variant. test_wordpool.py locks the invariant in CI: every answer must be lowercase alpha, correct length, unique, and present in words-5/6.json — so no future addition can become an unguessable puzzle. Co-Authored-By: Claude Opus 4.8 (1M context) --- goodnews/data/wordpool.json | 134 ++++++++++++++++++++++++++++++++++-- tests/test_wordpool.py | 20 ++++++ 2 files changed, 149 insertions(+), 5 deletions(-) create mode 100644 tests/test_wordpool.py diff --git a/goodnews/data/wordpool.json b/goodnews/data/wordpool.json index 69f7f74..5f6d5ca 100644 --- a/goodnews/data/wordpool.json +++ b/goodnews/data/wordpool.json @@ -1,101 +1,225 @@ { "5": [ +"adore", +"agile", +"alive", +"amaze", "ample", -"amply", +"angel", +"arise", +"aroma", "award", +"aware", +"beams", +"bless", "bliss", "bloom", +"blush", "bonus", "brave", +"brisk", "charm", "cheer", +"chime", +"clean", "clear", +"climb", +"craft", +"daisy", +"dance", +"dawns", "dream", +"drift", +"eager", +"earth", +"elate", +"enjoy", +"faith", +"fancy", "favor", +"feast", "fresh", "gifts", +"glade", +"gleam", +"glide", +"glory", "glows", "grace", +"grand", "green", +"grins", "happy", "heals", "heart", "honor", "hopes", +"humor", "ideal", +"jewel", +"jolly", +"laugh", "learn", "light", "lucky", +"magic", +"maple", "mends", "mercy", +"merit", "merry", +"mirth", +"music", "noble", +"oasis", "peace", +"plant", +"pluck", +"poise", +"pride", "prize", +"proud", "quiet", -"reach", +"quilt", "ready", "relax", "renew", +"river", "savor", "share", "shine", "smile", +"space", +"spark", +"stars", "still", "sunny", +"sweet", +"swift", "teach", "thank", "treat", "trust", "truth", +"tulip", "unity", "value", -"vital" +"vigor", +"vital", +"vivid", +"water", +"winds", +"wings", +"witty", +"worth", +"youth", +"yummy", +"zesty" ], "6": [ +"adored", +"ascend", +"aspire", "beauty", "bestow", +"better", +"bouncy", +"breeze", "bright", -"credit", +"bubbly", +"calmly", +"caring", +"cheery", +"cherub", +"chirpy", +"clever", +"dainty", +"dazzle", "devote", +"divine", +"dreamy", +"earthy", "esteem", +"family", +"flower", +"fondly", +"forest", +"friend", +"garden", "gather", +"genial", "gentle", "giving", +"glossy", +"golden", "growth", "health", +"heaven", +"honest", "joyful", +"joyous", "kindly", +"laurel", "lively", "lovely", +"loving", "mellow", "mended", +"morale", "nature", +"nestle", +"nicely", +"nuzzle", +"please", +"plenty", "praise", +"pretty", +"prized", +"purify", +"purity", +"quaint", "reborn", +"refine", +"relish", +"renews", "repair", "rescue", "revive", "reward", +"savior", +"savory", "secure", "serene", +"settle", "simple", "smiled", +"smooth", "soothe", "spirit", +"spring", +"sprout", "steady", "strong", "summit", "superb", +"supple", "tender", "thanks", "thrive", +"unfold", "united", "uplift", "valued", +"velvet", +"verity", "vision", +"voyage", +"warmly", "warmth", +"willow", "wisdom", -"wonder" +"wonder", +"zenith", +"zephyr" ] } \ No newline at end of file diff --git a/tests/test_wordpool.py b/tests/test_wordpool.py new file mode 100644 index 0000000..be86c91 --- /dev/null +++ b/tests/test_wordpool.py @@ -0,0 +1,20 @@ +import json +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent + + +def test_wordpool_answers_are_valid_and_guessable(): + """Every daily-word answer must be lowercase alpha, the right length, unique, + and present in the bundled guess dictionary — so no answer is ever unguessable. + Locks the 'code disposes' invariant against future pool additions.""" + pool = json.loads((ROOT / "goodnews" / "data" / "wordpool.json").read_text()) + for variant, n in (("5", 5), ("6", 6)): + dictwords = set(json.loads((ROOT / "frontend" / "static" / f"words-{n}.json").read_text())) + answers = pool[variant] + assert answers, f"{variant}-letter pool is empty" + assert len(answers) == len(set(answers)), f"{variant}-letter pool has duplicates" + for w in answers: + assert isinstance(w, str) and w.isalpha() and w.islower(), f"bad token: {w!r}" + assert len(w) == n, f"{w!r} is not {n} letters" + assert w in dictwords, f"{w!r} not in the guess dictionary → would be unguessable"