Code-review fixes on the stuck-adventurer minting path:
- AdminBuildConfirmedCharacter now runs race/class through parseRace/
parseClass (same as !setup), so a typo or non-playable class errors
instead of silently minting a 1-HP/AC-10/no-spell sheet; inputs are
normalized too.
- Clamp level to dndMaxLevel to match the L20 cap enforced elsewhere.
- CLI parses/validates every spec before db.Init, so a malformed spec
mid-batch no longer leaves earlier specs already committed.
The boredom ticker needs a confirmed dnd_character, so two populations
never leave on their own: veteran legacy players with an
adventure_characters row but no dnd_character (auto-migration only fires
on active play, which an idle player never does), and players who
abandoned !setup at race pick (pending_setup=1). Both are correct
guards in tryBoredomStart, not bugs — the fix is to hand them a finished
sheet.
AdminBuildConfirmedCharacter forces a race/class/level and reuses the
same constructors as auto-migration and !setup confirm (class-tuned
standard array, racial mods, HP/AC, resource pool, caster spells+slots),
with auto_migrated=1 so the player can freely !setup-rebuild the class
that was chosen for them. cmd/char-migrate is the one-off that drives it
against a live gogobee.db.