# Task: Consolidated TokenManager Recovery Fix

**File:** `keepa_deals/token_manager.py` (primary). Possibly `keepa_deals/smart_ingestor.py` for the backfiller throttle in Part 4.
**Spec:** `Documentation/Token_Management_Strategy.md` — all four fixes are already described there; this task makes the code match the spec.

Four related bugs let the Keepa token balance fall into an unrecoverable deficit after the Keepa plan was upgraded from 5→25 tokens/min. Symptom: the Smart Ingestor aborts every 5-minute cycle in "Recharge Mode," the newest dashboard deal ages to hours instead of minutes. Work symptoms-not-theories: verify each bug against the live code before editing. Each Part ends with a STOP-and-confirm checkpoint — post the requested output and wait for my OK before starting the next Part.

## Part 1 — BURST_THRESHOLD default (blocking)

Line ~37 sets `self.BURST_THRESHOLD = 280` as the initial guess. The spec (`Token_Management_Strategy.md`, Keepa section) caps the burst target at **50** for refill rates ≥ 20/min precisely "to prevent livelocks where tasks exit continuously while waiting for 150+ tokens." 280 is above the point where the recharge wait exceeds the 60s `TokenRechargeError` abort limit, so the ingestor can never climb out. Change the line-37 default from `280` to `50` so that even if dynamic adaptation never fires (see Part 3), the floor is livelock-proof. Do NOT change the correct adaptive values at lines ~93/95/99 (40/40/50). **STOP:** show the changed line and confirm 93/95/99 are untouched.

## Part 2 — force-sync must bypass the throttle in Recharge Mode

When the balance is critically low the code logs "Executing FORCE SYNC to verify state" but then logs "Skipping sync_tokens (throttled, force=True, elapsed=…s)" — the 5-minute sync throttle (`keepa_last_sync_timestamp`, `REDIS_KEY_LAST_SYNC_TIMESTAMP`) is blocking the very sync meant to rescue the worker, so it acts on a stale balance and aborts. Find where the throttle is enforced (around line ~506) and ensure that when `force=True`, the throttle is bypassed — a forced sync should always hit Keepa's `/token` endpoint. Keep the throttle for non-forced (routine) syncs. **STOP:** show the before/after of the throttle check and explain in one line how `force=True` now bypasses it.

## Part 3 — reconcile Redis token count to Keepa's truth on every forced sync

Live evidence showed Redis `keepa_tokens_left` drifting to -229 while Keepa's own `/token` endpoint reported -104 — the local counter over-counts consumption and diverges from Keepa's real balance. On every successful forced sync, overwrite Redis `keepa_tokens_left` (`REDIS_KEY_TOKENS`) with the authoritative `tokensLeft` value returned by Keepa, and call `_adjust_burst_threshold()` immediately after updating `REFILL_RATE_PER_MINUTE` (the pattern already at lines ~132–133 and ~550–551 — confirm it fires on the forced-sync recovery path too). This makes Keepa the source of truth and self-corrects drift each cycle. **STOP:** show the reconciliation write and confirm `_adjust_burst_threshold()` runs after the rate is set on the forced-sync path.

## Part 4 — lightweight-update backfiller must respect the recharge floor

With ~1,700 "zombie"/incomplete deals flagged for Lightweight Updates (`_process_lightweight_update`, per `Data_Logic.md` §2), the background repair loop issues Keepa product lookups that compete with the ingestor for the shared Redis token bucket, draining faster than 25/min refills. Confirm whether the lightweight-update path checks the same recharge guard / `MIN_TOKEN_THRESHOLD` before spending. If it does not, gate it so it skips (or defers) when the shared balance is in Recharge Mode, so recovery isn't starved by self-repair. Do not change the repair logic itself — only add the token-floor guard. **STOP:** show where the guard was added and confirm the repair logic is otherwise unchanged.

## Workflow notes

- Symptoms not theories: verify each bug in the live code before editing; if a Part's premise doesn't match what you find, stop and tell me rather than forcing the change.
- No DB migration and no destructive Redis commands in this task. If a manual Redis reset seems needed to test, describe it and wait — do not run `FLUSHALL`.
- Do NOT write the dev log until I explicitly request it (see start-session policy).
- After all four Parts are approved, I will deploy via `deploy_update.sh` and watch one ingestor cycle to confirm it proceeds past "Step 1" and saves deals.
