Adv 2.0 D&D layer: Phases 1-8 + Phase 9 SP1+SP2

Combines all uncommitted D&D work into one checkpoint:

Phases 1-8 (per gogobee_dnd_session_summary.md):
- Race/class/stats system, !setup flow, !sheet, !respec
- d20-vs-AC combat with race/class passives, auto-migration
- XP/level-up, skill checks, NPC refund hooks
- Equipment slot mapping, rarity, !rest short/long
- Pre-arm active abilities, resource pools
- Bestiary, !roll/!stats/!level, onboarding DM
- Audit fixes A-I, flavor wiring under internal/flavor/
- Phase 8 weapon dice + armor AC tables (gogobee_equipment_appendix)

Phase 9 SP1 — spell system foundations:
- 79 SpellDefinitions (76 in-scope + 3 reaction-deferred)
- dnd_known_spells, dnd_spell_slots tables
- pending_cast / concentration_* columns on dnd_character
- Slot tables for Mage/Cleric/Ranger, DC + attack-bonus math
- Long-rest refreshes slots; respec wipes spell state
- Auto-grant default known list on !setup confirm and auto-migration

Phase 9 SP2 — !cast / !spells / !prepare commands:
- Out-of-combat HEAL and UTILITY resolve immediately
- Damage/control/buff queue as pending_cast for next combat
- Audit-style save-then-debit, slot refund on save failure
- !cast --drop, concentration supersession, prep-cap enforcement
- Reaction spells refused with Phase 11 note

SP3 (combat-time resolution of pending_cast) and SP4 (full prep/learn
tests) are next. Build clean, full test suite green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-05-08 08:21:44 -07:00
parent 8e0fe0230c
commit 9e1a1f606c
80 changed files with 19088 additions and 210 deletions

162
CHANGELOG-2026-04-08.txt Normal file
View File

@@ -0,0 +1,162 @@
GOGOBEE CHANGELOG — 2026-04-08
================================
6 commits, 76 files changed, ~3,000 lines added
────────────────────────────────────────────────────────────────────────────────
1. ADVENTURE 2.5 — STEPS 1-2: ACTION ECONOMY & CHAT LEVEL LOOKUP
────────────────────────────────────────────────────────────────────────────────
- Split daily actions into combat (1) and harvest (3) instead of 3 generic.
Players can now do 1 combat + 3 harvest per day instead of choosing 3 from
either pool.
- Added cross-plugin chat level lookup so adventure perks can read XP levels
from the main XP plugin.
- Updated character sheet to show combat/harvest action counts separately.
- Refactored adventure command dispatch for the new action types.
Files: adventure.go, adventure_character.go, adventure_render.go,
adventure_babysit.go, adventure_events.go, adventure_scheduler.go,
adventure_twinbee.go, xp.go, db.go, main.go
────────────────────────────────────────────────────────────────────────────────
2. ADVENTURE 2.5 — STEPS 3-6: CHAT LEVEL PERKS
────────────────────────────────────────────────────────────────────────────────
- Chat Level XP Bonus: +5% adventure XP per 10 chat levels, capped at +25%.
- Chat Level Rare Drop Bonus: +0.5% rare drop rate per 10 chat levels,
capped at +2.5%.
- Shop Greeting: Luigi's greeting changes at chat levels 10, 30, and 50.
- Death Pardon: Chat level 30+ grants one free death pardon per week.
Pardoned players keep their streak and skip the death timer.
Files: adventure_chat_perks.go (new), adventure.go, adventure_arena.go,
adventure_character.go, adventure_masterwork.go, adventure_shop.go,
adventure_treasure.go, db.go
────────────────────────────────────────────────────────────────────────────────
3. ADVENTURE 2.5 — STEPS 7-9: ARENA STREAK SYSTEM
────────────────────────────────────────────────────────────────────────────────
- Replaced per-tier arena entry with a continuous streak starting at Tier 1.
- Players fight through T1-T5 sequentially. After each tier, a 30-second
countdown starts with real-time message edits. Type !bail to cash out,
or auto-advance to the next tier.
- Per-tier euro multipliers: T1=1.0x, T2=1.5x, T3=2.0x, T4=2.75x, T5=4.0x.
- XP multiplier at payout based on tiers cleared: 1.0x/1.2x/1.5x/1.85x/2.5x.
- Death forfeits ALL accumulated rewards (euros + XP).
- Gladiator's Helm: streak-exclusive Masterwork-tier drop (8% at T4, 18% T5).
- Removed old commands: !arena tier N, !arena descend, !arena cashout.
- Added !bail command and countdown goroutine with message editing.
- Restart recovery: stale active/awaiting runs auto-bail on bot restart.
Files: adventure_arena.go (major rewrite), adventure_arena_render.go,
adventure.go, adventure_arena_test.go, db.go
────────────────────────────────────────────────────────────────────────────────
4. BUG FIXES & POLISH
────────────────────────────────────────────────────────────────────────────────
- Fixed streak grace period calculation in adventure scheduler.
- Fixed UNO earnings tracking not crediting properly.
- Fixed hospital UX: cleaner admission flow, insurance billing display.
- Added wordle/lottery atomicity: ticket purchases and wordle completions
now use proper transactions.
- Added !adv alias for !adventure.
- Hospital insurance billing now shows itemized breakdown.
- Fixed character sheet showing wrong holiday action count.
- Removed dead holiday prompt code.
- Capped babysit counter to prevent unbounded growth.
Files: adventure_character.go, adventure_hospital.go, adventure_scheduler.go,
adventure_babysit.go, adventure_render.go, lottery.go, lottery_db.go,
lottery_draw.go, wordle.go, stats.go, urls.go, llm_passive.go
────────────────────────────────────────────────────────────────────────────────
5. FULL CODEBASE AUDIT — 21 FIXES
────────────────────────────────────────────────────────────────────────────────
CRITICAL:
- Credit()/Debit() now reject non-positive amounts. Previously, a negative
amount could mint or drain euros with no validation.
- Lottery ticket purchase moved count check inside DB transaction, closing
a TOCTOU race where concurrent buys could exceed the 100-ticket cap.
HIGH:
- Arena bail channel ownership reworked. The countdown goroutine and bail
handler now use LoadAndDelete to claim exclusive ownership of the channel,
preventing double-close panics.
- Added safeGo() panic recovery wrapper. Applied to 17 goroutine launch
sites across 14 plugin files. A panic in any async handler previously
killed the entire daemon.
- Entry.ID validated before exec.Command in fetch-esteemed (path traversal).
- Silently ignored DB errors in lottery_db.go now logged.
MEDIUM:
- Added database indexes: idx_arena_runs_user(user_id, status) and
idx_euro_bal_user(user_id) for high-traffic query paths.
- db.Close() function added; called on SIGINT/SIGTERM shutdown.
- Miniflux mutex pattern fixed: snapshot pollingDisabled under lock,
check after unlock (was Lock/early-return/Unlock without defer).
- JSON unmarshal errors in lottery history/tickets now logged instead
of silently discarded.
- Internal error details no longer leaked to users in forex and esteemed
responses (was showing raw %v error strings).
LOW:
- "Failed to load character" error now suggests !adventure.
- Empty !buy args shows usage hint instead of "No item matching ''".
FALSE POSITIVES VERIFIED:
- fun.go array access (bounds checks exist at L441, L591).
- adventure_twinbee.go filtered[0] (empty check at L90).
- wotd.go defs[0] (empty check at L102).
- moderation.go timer overwrite (existing.Stop() called at L799).
- All rate-limit callers already provide user feedback.
Files: euro.go, lottery_db.go, adventure_arena.go, plugin.go, db.go,
main.go, forex.go, esteemed.go, miniflux.go, adventure.go,
fetch-esteemed/main.go, + 14 plugin files (safeGo conversions)
────────────────────────────────────────────────────────────────────────────────
6. TEST COVERAGE — 328 TESTS ACROSS 4 PACKAGES
────────────────────────────────────────────────────────────────────────────────
NEW TEST FILES:
- internal/util/parser_test.go (30 tests)
XPForLevel, LevelFromXP, round-trip for 0-100, ProgressBar edge cases,
IsCommand, GetArgs, HasNonASCII, ParseMessage
- internal/crypto/crypto_test.go (12 tests)
Encrypt/Decrypt round-trip, empty plaintext, different nonces,
wrong key rejection, HMAC determinism/length, ParseKey validation
- internal/plugin/helpers_test.go (30 tests)
formatNumber, formatNumberInt64, normalizeExpression (natural language,
prefix stripping, commas, percent-of), formatCalcResult, countMatches,
formatLotteryNumbers, generateLotteryNumbers (count, range, sorted,
unique), joinNames, chatLevelXPBonus, chatLevelRareBonus, shopGreeting
- internal/plugin/audit_fixes_test.go (21 tests)
safeGo panic recovery (normal, panic, nil panic), bail channel
ownership transfer (both directions), arena status renders for
indexed states, lottery edge cases, error message leak checks,
UX guidance verification, integer overflow guards, regression guards
- internal/db/db_test.go (4 tests)
Init/Close lifecycle, idempotent Init, schema index verification,
schema runs cleanly against fresh SQLite
EXISTING TESTS (pre-existing, not written today):
- adventure_arena_test.go: 55 (51 pre-existing + 4 added)
- adventure_shop_test.go: 26
- uno_test.go: 20
- adventure_test.go: 17
- holdem_tips_test.go: 16
- adventure_holidays_test.go: 15
- wordle_game_test.go: 9
- holdem_eval_test.go: 8
- blackjack_test.go: 7
TOTAL: 328 tests, 0 failures, 4 packages covered