#29342 [Bug]: LiteLLM_SpendLogToolIndex is never pruned — grows unbounded, orphaned after spend log retention cleanup
## Description
`LiteLLM_SpendLogToolIndex` is insert-only and has **no retention / pruning anywhere in the codebase**. When the spend-log retention cleanup (`maximum_spend_logs_retention_period`) deletes old `LiteLLM_SpendLogs` rows, the matching `SpendLogToolIndex` rows are **left behind**, so orphaned tool-index rows accumulate and the table grows without bound — even when retention is correctly configured.
## Root cause
1. **No cascade.** `LiteLLM_SpendLogToolIndex` has no foreign key to `LiteLLM_SpendLogs`; its only constraint is `PRIMARY KEY (request_id, tool_name)` (see `schema.prisma` and the `..._add_spend_log_tool_index/migration.sql`). So deleting a `SpendLogs` row does not remove its tool-index rows.
2. **Cleanup deletes `SpendLogs` only.** `SpendLogCleanup._delete_old_logs` (`litellm/proxy/db/db_transaction_queue/spend_log_cleanup.py`) runs: ```sql DELETE FROM "LiteLLM_SpendLogs" WHERE "request_id" IN ( SELECT "request_id" FROM "LiteLLM_SpendLogs" WHERE "startTime" < $1::timestamptz LIMIT $2 ) ``` It never touches `LiteLLM_SpendLogToolIndex`.
3. **No delete path exists anywhere.** The only references to `SpendLogToolIndex` in the rep…