The A1 regex banned \b\d+d\d+\b (e.g. '1d20') but missed bare die
notation ('d20', 'd6') with no leading count. SRD's 'blink' Description
slipped through with 'Roll a d20 at the end of each of your turns...'.
- Add \bd(4|6|8|10|12|20|100)\b ban to the prose regex sweep.
- Add hand-authored overlay shim for blink in dnd_spells_data.go.
Classes union with SRD preserves Cleric/Sorcerer/Warlock availability.
Test now passes the wider sweep; no other reachable spells leak.
The audit plan flagged jargon leaks in the SRD spell prose surfaced by
!cast and !spellbook. Verifying against HEAD turned up two corrections
to the plan's framing:
- The overlay in dnd_spells_data.go wins on ID collision, so for the
~76 hand-authored spells the *overlay* Descriptions are what players
actually see — and those were crunchier than the SRD ("Heal 1d8 +
WIS mod HP. Touch.", "8d6 fire in 20 ft radius. DEX save half.",
etc.). Touching only the generated SRD file would have missed the
bigger leak.
- The Upcast field is never displayed at runtime (only the import
generator reads it), so testing it against the regex would test
dead data.
So this commit:
- rewrites every overlay Description into playful, jargon-free flavor
in the charm_person voice ("Sweet-talk a humanoid…") — no dice, no
saves, no AC math, no ability-mod references
- adds 31 overlay shims for SRD-only spells whose generated text was
broken (placeholder gaps from the Open5e classifier — "no larger
than a.", "up to to", "in a in range"), empty ("You touch a
creature."), typo-laden ("magicou", "undeadou", "diseasesou"), or
jargon-heavy (false_life's "1d4+4 temporary hit points")
- adds TestSpellDescriptionsAreJargonFree, a regex sweep over the
merged registry that bans "saving throw", "spell slot of",
"ability modifier", "hit points equal to", and \bNdN\b dice
notation. Currently passing; will fail-loud on regressions or new
SRD imports that need overlay shims.
The generated dnd_spells_srd_data.go is left untouched — overlay is
the regen-safe surface per its own header comment.
B2: Removed shield/counterspell from Mage/Sorcerer defaults and hellish_rebuke/counterspell
from Warlock — reactions are EffectReaction and combat has no reaction window yet, so
auto-granting them just litters the spellbook with dead entries. Substituted L1/L3
staples (sleep, fly, burning_hands, chromatic_orb where class-tagged appropriately).
B3: Replaced the stale "Mage, Cleric, Ranger, and Arcane Trickster (L5+)" enumeration in
!cast/!spells learn/!prepare error paths with class-aware route hints via a new
spellRouteHintFor() helper.
R15: Removed the duplicate hand-authored healing_word_spell entry; Cleric default now
references the canonical SRD healing_word (cleric/druid/bard tagged). parseSpell
and lookupSpell now resolve "healing word" deterministically.
R16: !cast --drop now appends "(slot refunded)" when applicable.
R17: Prep-cap message rewritten to "Your prepared list is full (N/N)."
R19: Removed shillelagh from Druid default — the overlay flags it cleric/ranger only and
it has no real attack profile yet (BuffSelf, no DamageDice).
Bonus correctness: dndSpellRegistry now unions Classes on overlay collision instead of
replacing wholesale. The hand-authored buildSpellList() entries were tagged Mage-only,
so every Sorcerer/Warlock/Bard/Druid spell that collided with the SRD silently lost its
class list — meaning auto-granted defaults were rejected at the classOK gate. Union
merge restores SRD coverage without forcing a hand-edit of every overlay entry.
Tests:
- TestDefaultKnownSpellsHaveNoReactions covers B2.
- TestDefaultKnownSpellsAreCastableByClass guards the overlay-narrow regression.
- TestHealingWordResolvesDeterministically covers R15.
- TestCastNonCasterErrorHasNoClassEnumeration covers B3.
- Existing dnd_prepare_test.go updated to reference healing_word.