From b0d57936c2eb202f0697777fa04e07ac3200ab15 Mon Sep 17 00:00:00 2001 From: duang777 Date: Fri, 13 Nov 2026 17:45:51 +0800 Subject: [PATCH] fix(quota): cover all history instead of crashing on an unrepresentable window goal_quota_with_spend_ledger subtracts timedelta(hours=window_hours) from the current time. configure-goal accepts any finite positive --quota-window-hours, and a registry can carry any number, so a value of 1e8 hours or more makes the subtraction raise OverflowError (and 1e12 overflows the timedelta itself). collect_history evaluates every registered Goal in one pass, so one Goal with such a window made `status` and every quota read fail for the whole registry, including Goals with a normal 24 hour window. An unrepresentably long window covers every representable event, so the window start is now the earliest datetime in the current time's zone. The Goal keeps its configured window_hours and still counts all of its spends. Co-Authored-By: Claude Sonnet 5.5 Signed-off-by: duang777 --- loopx/quota.py | 7 ++++++- .../test_quota_rolling_window_projection.py | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/loopx/quota.py b/loopx/quota.py index eded708cd4..3a6c6a7684 100644 --- a/loopx/quota.py +++ b/loopx/quota.py @@ -399,7 +399,12 @@ def goal_quota_with_spend_ledger( current_time = now or datetime.now(timezone.utc).astimezone() if current_time.tzinfo is None: current_time = current_time.replace(tzinfo=timezone.utc) - window_start = current_time - timedelta(hours=int(payload["window_hours"])) + try: + window_start = current_time - timedelta(hours=int(payload["window_hours"])) + except OverflowError: + # A window longer than datetime can represent still covers every + # representable event. It must not crash the Goal-wide history read. + window_start = datetime.min.replace(tzinfo=current_time.tzinfo) contributions: list[tuple[str, str, int]] = [] spend_event_count = 0 void_event_count = 0 diff --git a/tests/control_plane/test_quota_rolling_window_projection.py b/tests/control_plane/test_quota_rolling_window_projection.py index 477dce99fb..9e78f55153 100644 --- a/tests/control_plane/test_quota_rolling_window_projection.py +++ b/tests/control_plane/test_quota_rolling_window_projection.py @@ -3,6 +3,8 @@ from datetime import datetime, timezone from typing import Any +import pytest + from loopx.quota import goal_quota_with_spend_ledger @@ -123,3 +125,20 @@ def test_rolling_counter_isolated_by_exact_goal_instance() -> None: assert current["spend_event_count"] == 1 assert legacy_owner["spent_slots"] == 1 assert legacy_owner["spend_event_count"] == 1 + + +@pytest.mark.parametrize("window_hours", [10**8, 10**12, 1e12]) +def test_unrepresentable_window_covers_all_history_without_crashing( + window_hours: float, +) -> None: + goal = _goal() + goal["quota"]["window_hours"] = window_hours + spent = _spend("2026-01-01T00:00:00+00:00", "turn-1") + + ledger = goal_quota_with_spend_ledger( + goal, + [spent], + now=datetime(2026, 6, 1, tzinfo=timezone.utc), + ) + + assert ledger["spent_slots"] == 1