Blackjack and RPS PvP deduct a stake up front and held it only in an in-memory
View - a restart mid-hand lost the coins. Now the stake is escrowed on the user
record (new pending_wager JSON field) in the SAME commit as the deduction, and:
- do_blackjack_bet accumulates the escrow (covers double/split); do_blackjack_payout
clears it on settlement (incl. the 0-payout loss/timeout paths).
- do_rps_pvp_deposit records it; do_rps_pvp_payout/refund clear it, and a new
do_rps_pvp_forfeit clears the loser's marker (their stake went to the winner).
- reconcile_pending_wagers() runs on startup (on_ready) and refunds any stake left
escrowed by an interrupted game. It's idempotent and locks per user.
Schema: pending_wager auto-types as json via sync_pb_schema. Tests cover the full
escrow lifecycle, loser forfeit, and idempotent reconciliation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VbAVsrZuYesea99mPMmPT
- do_blackjack_bet now wraps its _commit so a DB failure returns db_error
(handled by the command layer) instead of raising through the interaction.
- DEV_NOTES "Adding a New Economy Command" checklist updated: use
effective_cooldown / store.ITEM_COOLDOWNS as the single source of truth for
item-modified cooldowns, and handle db_error via reply_db_error.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VbAVsrZuYesea99mPMmPT
Vanity shop (/vanity): cosmetic badges/titles as a pure whale coin sink -
purchases burn coins (not credited to the house) and equip a badge shown on
/profile. New vanity_owned/vanity_active fields, schema sync, and tests.
Money-safety and robustness fixes from a codebase review:
- _parse_amount now rejects negative amounts. Every bet/give/request flows
through it, so a negative value can no longer mint coins on a loss/transfer
path that trusts the caller's sign (all call sites already guarded <= 0;
this closes the source).
- do_blackjack_payout no longer raises on a DB failure. The stake was already
deducted in do_blackjack_bet, so it now logs critical with the owed amount
(for admin reconciliation) and returns db_error; all payout call sites render
a clear "payout failed" notice instead of crashing the interaction.
- Instant "kohv" consumable now cancels the pending reminder DMs for the
cooldowns it wipes (via new INSTANT_RESET_COMMANDS), so no stale/duplicate
reminders fire.
- Renamed the misleadingly-named _refund_user_safe -> _debit_house_safe (it
debits the house) and dropped its ignored first arg.
- Added __all__ to vanity.py and consumables.py so `import *` no longer leaks
incidental imports into the economy namespace.
- Documented Kõrvaklapid's +25 coin daily bonus in README and DEV_NOTES.
Tests: blackjack payout DB-failure safety and INSTANT_RESET_COMMANDS lockstep.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VbAVsrZuYesea99mPMmPT