You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As a platform engineer / org-lead,
I want the agent fleet to pause automatically when the rolling 7-day Claude subscription budget crosses a threshold that tightens as the weekly reset approaches — reserving ~2% of the weekly budget per remaining day — so that the fleet cannot burn the whole week's budget in the first two days,
so that a human always has usable Claude headroom for the rest of the week, and the maintainer no longer has to notice budget pressure manually and withhold a secret to stop the bleeding.
Phase 5 (#641) breaks on the 5-hour window at a static threshold (default 90%). That protects against a short burst, but it is blind to the shape of the week: the fleet can sit under 90% of every 5-hour window and still exhaust the 7-day budget by Thursday, leaving four days with nothing for humans.
This story adds the orthogonal control — a time-varying threshold on the 7-day window:
pause when weekly_all.percent >= 100 - (reserve_pct_per_day * days_until_weekly_reset)
With reserve_pct_per_day = 2 and the reset derived from the API's resets_at (Tuesday ~11:00 America/Chicago, confirmed by live probe — see #637):
Day (relative to reset)
Days left
Pause at
Tuesday (reset day)
0
100%
Monday
1
98%
Sunday
2
96%
Saturday
3
94%
Friday
4
92%
Thursday
5
90%
Wednesday
6
88%
Tuesday (just reset)
7
86%
The floor of 86% immediately after a reset is intentional: it is the "don't spend the whole week on day one" guard. The ceiling of 100% on reset day is also intentional: with the budget minutes from refilling, there is nothing left to protect.
Motivating observation (2026-08-20): a live probe of the usage endpoint showed the account-wide weekly window at 85% with five days left before reset — one point under this story's Thursday threshold, with a model-scoped weekly limit already exhausted. The #641 5-hour breaker would not have fired at any point on that path.
Cross-repo companion (private): the hourly poller, the credential, and the org-variable write live in petry-projects/.github-private. Filed separately.
The pause switch itself already exists: AGENTS_PAUSED=true (Actions variable, chosen because variables are visible where secrets are not), delivered by .github-private#1525. This story automates setting and clearing it; it does not redesign it.
Acceptance Criteria
The gate evaluates a 7-day glide-path threshold from an org_wide.token_budget.seven_day block in standards/agent-rate-limits.json — at minimum enabled, reserve_pct_per_day (default 2), floor_pct, and ceiling_pct. No threshold is hardcoded, and the schedule is expressible purely as config.
days_until_reset is derived from the telemetry payload's resets_at, never from a hardcoded weekday, cron expression, or timezone constant. Partial days round up, so the day before reset evaluates as 1 day left (98%), not 0.
The evaluation keys on the account-wide weekly window (limits[].kind == "weekly_all"). A weekly_scoped (per-model) limit at critical / is_activemust not trip a fleet pause — the correct response to scoped exhaustion is the engine's existing model-fallback chain. This distinction is asserted by a test.
On trip, the pause is surfaced through the existing human-clearable marker/label convention used by the rest of the library, and the reason is machine-readable (which window, observed percent, threshold, reset timestamp) rather than prose buried in a log line.
Telemetry failure (non-200, malformed body, missing weekly_all entry) degrades to allow-with-warning per the ADR's documented default — an outage of an undocumented third-party endpoint must never stop the fleet.
Rollout is dry-run first — the gate logs the decision it would have made for a full week before it can defer anything — and activation respects the epic's Phase-2 human sign-off gate.
Tasks / Subtasks
Add the seven_day glide-path block to standards/agent-rate-limits.json + companion doc (AC: Addressing PR comments #1)
Pause semantics: the breaker gates new dispatch only. In-flight runs finish under the existing per-tier engine timeouts — killing work mid-flight wastes the tokens already spent and leaves PRs in a partial state.
Auto-clear is the subtle half. The pause must record that it set AGENTS_PAUSED, so the auto-resume after the weekly reset clears only its own pause and never a pause a human set deliberately. A companion marker (e.g. AGENTS_PAUSE_SOURCE=weekly-glide) is the cheapest way; the resume path checks it before clearing. Without this, an automated resume silently overrides a maintainer's decision — the inverse of the failure .github-private#1525 was filed to fix.
Hysteresis: once tripped, do not un-trip merely because usage percentage ticks back under the line (it will not — utilization is monotonic within a window). The only clean resume is the window reset, which is exactly what resets_at gives.
Non-goal: this story does not change model selection, the engine fallback chain, or the 5-hour breaker.
TDD (AGENTS.md): unit tests mock the telemetry source; no live network.
Project Structure Notes
Extends scripts/lib/agent-rate-limit.sh (Phase 3) and standards/agent-rate-limits.json (Phase 2), reusing Phase 5's telemetry adapter. New test under tests/. The poller and the org-variable write are cross-repo (private).
Story
As a platform engineer / org-lead,
I want the agent fleet to pause automatically when the rolling 7-day Claude subscription budget crosses a threshold that tightens as the weekly reset approaches — reserving ~2% of the weekly budget per remaining day — so that the fleet cannot burn the whole week's budget in the first two days,
so that a human always has usable Claude headroom for the rest of the week, and the maintainer no longer has to notice budget pressure manually and withhold a secret to stop the bleeding.
Context — why this is separate from #641
Phase 5 (#641) breaks on the 5-hour window at a static threshold (default 90%). That protects against a short burst, but it is blind to the shape of the week: the fleet can sit under 90% of every 5-hour window and still exhaust the 7-day budget by Thursday, leaving four days with nothing for humans.
This story adds the orthogonal control — a time-varying threshold on the 7-day window:
With
reserve_pct_per_day = 2and the reset derived from the API'sresets_at(Tuesday ~11:00 America/Chicago, confirmed by live probe — see #637):The floor of 86% immediately after a reset is intentional: it is the "don't spend the whole week on day one" guard. The ceiling of 100% on reset day is also intentional: with the budget minutes from refilling, there is nothing left to protect.
Motivating observation (2026-08-20): a live probe of the usage endpoint showed the account-wide weekly window at 85% with five days left before reset — one point under this story's Thursday threshold, with a model-scoped weekly limit already exhausted. The #641 5-hour breaker would not have fired at any point on that path.
Prerequisites
GET https://api.anthropic.com/api/oauth/usageverified first-hand; see the ADR comment for endpoint, headers, response schema, and risks.seven_dayblock beside Phase 5'sfive_hourblock.petry-projects/.github-private. Filed separately.AGENTS_PAUSED=true(Actions variable, chosen because variables are visible where secrets are not), delivered by.github-private#1525. This story automates setting and clearing it; it does not redesign it.Acceptance Criteria
org_wide.token_budget.seven_dayblock instandards/agent-rate-limits.json— at minimumenabled,reserve_pct_per_day(default2),floor_pct, andceiling_pct. No threshold is hardcoded, and the schedule is expressible purely as config.days_until_resetis derived from the telemetry payload'sresets_at, never from a hardcoded weekday, cron expression, or timezone constant. Partial days round up, so the day before reset evaluates as 1 day left (98%), not 0.limits[].kind == "weekly_all"). Aweekly_scoped(per-model) limit atcritical/is_activemust not trip a fleet pause — the correct response to scoped exhaustion is the engine's existing model-fallback chain. This distinction is asserted by a test.weekly_allentry) degrades to allow-with-warning per the ADR's documented default — an outage of an undocumented third-party endpoint must never stop the fleet.tests/test_agent_rate_limit_weekly_glide.batsexercises a mocked telemetry source: threshold at each day-offset 0–7, boundary conditions (exactly at threshold trips; one point under does not), partial-day rounding, scoped-limit-must-not-trip (AC Add coding standards & principles section to AGENTS.md #3), and telemetry-unavailable fail-safe (AC Add stacked PR strategy and Epic-level workflow guidance #5). No live network.Tasks / Subtasks
seven_dayglide-path block tostandards/agent-rate-limits.json+ companion doc (AC: Addressing PR comments #1)days_until_resetfromresets_atwith round-up semantics (AC: Add multi-agent isolation strategy using git worktrees #2)scripts/lib/agent-rate-limit.sh, keyed onweekly_alland ignoringweekly_scoped(AC: Add coding standards & principles section to AGENTS.md #3)tests/test_agent_rate_limit_weekly_glide.batswith a mocked source (AC: feat: add Structured Logging and CQRS standards #6)Dev Notes
AGENTS_PAUSED, so the auto-resume after the weekly reset clears only its own pause and never a pause a human set deliberately. A companion marker (e.g.AGENTS_PAUSE_SOURCE=weekly-glide) is the cheapest way; the resume path checks it before clearing. Without this, an automated resume silently overrides a maintainer's decision — the inverse of the failure.github-private#1525was filed to fix.resets_atgives.Project Structure Notes
Extends
scripts/lib/agent-rate-limit.sh(Phase 3) andstandards/agent-rate-limits.json(Phase 2), reusing Phase 5's telemetry adapter. New test undertests/. The poller and the org-variable write are cross-repo (private).References
petry-projects/.github-private#1525—AGENTS_PAUSEDas a first-class state (the switch this automates)Likely target surface
standards/agent-rate-limits.json (extend — seven_day glide block)scripts/lib/agent-rate-limit.sh (extend — weekly glide evaluation)tests/test_agent_rate_limit_weekly_glide.bats (new)Filed as the follow-on to #641 for epic #636. Inert until a maintainer arms the epic.