fix(supervisor): re-probe claude.ai quota instead of blindly waiting for the reported reset #242

Merged
chaim merged 1 commits from worktree-supervisor-quota-probe into main 2026-06-13 09:36:20 +00:00
Owner

הבעיה (מה ש-chaim שאל: "למה זה לא חזר לעבוד מיד כשהמכסה התאפסה?")

כשהדריינר פגע ב-429, הסופרוייזר רשם את שעת-האיפוס שה-claude.ai דיווח ("resets 6:50pm UTC") והמתין בעיוורון עד אותה שעה — קרא אותה מחדש מה-state בכל טיק בלי לבדוק אם המכסה כבר חזרה. claude.ai משחרר מכסה לרוב מוקדם מהמדווח, אז הדריינר ישב רדום שעות אחרי שכבר יכול היה לרוץ, ורק בעיטה ידנית (ניקוי cooldown + הצתה) החזירה אותו.

התיקון

בכל טיק שבו היינו אחרת ב-hold, להריץ בדיקת-מכסה חיה זולה (quota_available() → קריאת claude -p זעירה, cost≈0) ולהתחדש מיד כשהיא מצליחה — לכל היותר בדיקה אחת לטיק (כל 15 דק'), ורק כשאנחנו חושבים שאנחנו חסומים. שמרני בכישלון (exit≠0 / timeout / הודעת-מגבלה → נשאר ב-hold), כך שבדיקה תקולה לא מחזירה את הדריינר אל תוך 429 אמיתי. נוסף claude_bin() שמאתר את ה-CLI גם כש-PATH ריק תחת pm2 cron.

אימות

  • quota_available() נבדק בפועל → החזיר True (תאם למציאות שהמכסה חזרה; ה-claude אותר נכון).
  • הסקריפט עובר ast.parse.
  • host-only — אין שינוי ב-web/, אז אין deploy לקונטיינר; סנכרון לסקריפט ה-host יבוצע אחרי merge.

Invariants

  • G1 — החלטת-החידוש נגזרת ממצב-המכסה האמיתי, לא מחותמת-זמן מנוחשת.
  • אין מסלול-בקרה חדש.

🤖 Generated with Claude Code

## הבעיה (מה ש-chaim שאל: "למה זה לא חזר לעבוד מיד כשהמכסה התאפסה?") כשהדריינר פגע ב-429, הסופרוייזר רשם את שעת-האיפוס שה-claude.ai דיווח (`"resets 6:50pm UTC"`) ו**המתין בעיוורון עד אותה שעה** — קרא אותה מחדש מה-state בכל טיק בלי לבדוק אם המכסה כבר חזרה. claude.ai משחרר מכסה לרוב **מוקדם** מהמדווח, אז הדריינר ישב רדום שעות אחרי שכבר יכול היה לרוץ, ורק בעיטה ידנית (ניקוי cooldown + הצתה) החזירה אותו. ## התיקון בכל טיק שבו היינו אחרת ב-`hold`, להריץ **בדיקת-מכסה חיה זולה** (`quota_available()` → קריאת `claude -p` זעירה, `cost≈0`) ולהתחדש מיד כשהיא מצליחה — לכל היותר בדיקה אחת לטיק (כל 15 דק'), ורק כשאנחנו חושבים שאנחנו חסומים. שמרני בכישלון (exit≠0 / timeout / הודעת-מגבלה → נשאר ב-hold), כך שבדיקה תקולה לא מחזירה את הדריינר אל תוך 429 אמיתי. נוסף `claude_bin()` שמאתר את ה-CLI גם כש-PATH ריק תחת pm2 cron. ## אימות - `quota_available()` נבדק בפועל → החזיר `True` (תאם למציאות שהמכסה חזרה; ה-`claude` אותר נכון). - הסקריפט עובר `ast.parse`. - **host-only** — אין שינוי ב-`web/`, אז אין deploy לקונטיינר; סנכרון לסקריפט ה-host יבוצע אחרי merge. ## Invariants - **G1** — החלטת-החידוש נגזרת ממצב-המכסה האמיתי, לא מחותמת-זמן מנוחשת. - אין מסלול-בקרה חדש. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chaim added 1 commit 2026-06-13 09:36:13 +00:00
fix(supervisor): re-probe claude.ai quota instead of waiting blindly for the reported reset
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 8s
013fe39ea7
When the halacha drain hit a 429, the supervisor recorded the reset time the
error reported (e.g. "resets 6:50pm UTC") and then HELD until that timestamp,
re-reading it from its own state every tick without ever checking whether quota
had actually returned. claude.ai usually frees up quota earlier than the message
claims, so the drain sat idle for hours after it could have resumed — and only a
manual kick (clear cooldown + trigger) got it going again.

Now, on any tick where we'd otherwise hold on a cooldown, run a cheap live probe
(`quota_available()` → a tiny `claude -p` call, cost ~0) and resume the instant
it succeeds — at most one probe per 15-min tick, only while we believe we're
limited. Conservative on failure (non-zero exit / timeout / limit message →
stay held), so a flaky probe never resumes the drain into a real 429. Adds a
claude_bin() resolver so the probe works under pm2 cron where PATH is bare.

Invariants: G1 (resume decision driven by actual quota state, not a guessed
timestamp); no new control path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
chaim merged commit 8d13e26cc8 into main 2026-06-13 09:36:20 +00:00
chaim deleted branch worktree-supervisor-quota-probe 2026-06-13 09:36:20 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ezer-mishpati/legal-ai#242