Symptom
On 2026-05-10 morning (~09:00 BST), action_schedule had 0 Daikin actions queued for the day despite the LP planning a tank lift to 65°C at 13:30 UTC + evening reheats. Plan ran fine; dispatch's budget guard pruned everything.
Root cause
src/scheduler/lp_dispatch.py:710-715:
reserve = int(getattr(config, "DAIKIN_RESERVE_FOR_HEARTBEAT", 30))
headroom = max(0, quota_remaining("daikin") - reserve)
Phase A (#308) removed Daikin calls from the heartbeat. The 24h rolling quota window still contained yesterday's pre-Phase-A burn (145/180 used). At plan-fire time, quota_remaining=31, headroom=31-30=1 → most LP-planned action pairs got pruned by _apply_write_budget.
The window will clear naturally by ~22:42 UTC (24h after Phase A deploy), so dispatch will recover today / tomorrow without intervention.
Why this is a real concern
Once steady-state, expected Daikin usage:
- Brief reads (08:00, 22:00 BST): ~4-10/day
- LP plan dispatches (multiple MPC fires): ~30-60/day
- Slot reconciles (cache-hit mostly): ~5-10/day
- Token refresh (lazy): ~3/day
- Total: ~50-80/day out of 180 budget
The 30-call reserve is sized for old heartbeat-era. With heartbeat now using 0/day, it's still meaningful safety buffer for slot-boundary reconciles + briefs + token refresh, but worth re-tuning once we observe ~14 days of steady-state usage.
Proposed actions
Not urgent — wait for self-recovery first.
Related
Symptom
On 2026-05-10 morning (~09:00 BST),
action_schedulehad 0 Daikin actions queued for the day despite the LP planning a tank lift to 65°C at 13:30 UTC + evening reheats. Plan ran fine; dispatch's budget guard pruned everything.Root cause
src/scheduler/lp_dispatch.py:710-715:Phase A (#308) removed Daikin calls from the heartbeat. The 24h rolling quota window still contained yesterday's pre-Phase-A burn (145/180 used). At plan-fire time,
quota_remaining=31,headroom=31-30=1→ most LP-planned action pairs got pruned by_apply_write_budget.The window will clear naturally by ~22:42 UTC (24h after Phase A deploy), so dispatch will recover today / tomorrow without intervention.
Why this is a real concern
Once steady-state, expected Daikin usage:
The 30-call reserve is sized for old heartbeat-era. With heartbeat now using 0/day, it's still meaningful safety buffer for slot-boundary reconciles + briefs + token refresh, but worth re-tuning once we observe ~14 days of steady-state usage.
Proposed actions
Not urgent — wait for self-recovery first.
api_call_log.DAIKIN_RESERVE_FOR_HEARTBEATbased on observed steady-state non-dispatch usage. Likely 10-15 instead of 30.DAIKIN_RESERVE_FOR_OPS.Related