GETDEL requires Redis 6.2+; server runs 6.0.16, so every finalize_balance
and refund_balance call failed silently ('Unknown Redis command called
from Lua script'). Consequences observed under concurrent load test:
- reserve:* keys leaked until 600s TTL instead of being released at finalize
- balance:{org} never reconciled with actual cost (over-deduction by
max_cost-actual accumulated per call)
- FAILED-request refunds silently lost
GET+DEL inside a Lua script executes atomically (single-threaded),
so the pop semantics are unchanged.
- balance.py: reserve_balance/finalize_balance/refund_balance with Lua
- utils.py: get_model_max_cost from llmusage history, update_model_max_cost
- init.py: register reserve_balance, finalize_balance, refund_balance on env
- chat/completions/index.dspy: reserve before inference, refund on exception
- DB migration: llm.max_cost DECIMAL(10,4) for historical max charge