quota: z.ai credit-bucket back-pressure + resource gate + usage accounting (Redmine 490+491)

The loop now consults quota and host state before every dispatch and
DEFERS gated work with a logged reason instead of letting turns die at
the provider (the 2026-08-28 19:00 quota-wall failure mode, replayed as
a test). Adds internal/quota: 5h/weekly credit buckets (provider poll
when z.ai ships an endpoint - fake-server tested - else locally
estimated from the documented credit formula), TZ-aware peak window
(default 01:00-05:00 America/Chicago weekdays, matching the documented
z.ai peak Mon-Fri 14:00-18:00 Singapore), block/defer thresholds, a
read-only load/mem/disk/IO-PSI monitor, an optional redis shared-state
hop (stdlib RESP2 mini-client) so all instances of an account
coordinate, per-class token+credit accounting in loop.jsonl, and
`harness quota status|probe|gate`. Config: [quota] + [resources]
sections; README runbook covers the redis container and deploy-time
cgroup enforcement.

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
This commit is contained in:
2026-08-29 05:37:15 -05:00
parent 9dbb20489c
commit fc518c475e
21 changed files with 2904 additions and 20 deletions
+77
View File
@@ -0,0 +1,77 @@
package quota
import (
_ "time/tzdata" // embedded zone database: TZ-aware windows work in scratch containers
"time"
"ukrrs.com/mopac/harness/internal/config"
)
// Schedule is the TZ-aware peak window. z.ai peak hours are documented as
// Monday-Friday 14:00-18:00 Singapore (UTC+8), which is 01:00-05:00
// America/Chicago in winter (CST) / 00:00-04:00 during US DST — the default
// matches Charles's "0100 to 0500 CST" and is configurable to the minute.
// The window may wrap midnight (start > end): then it covers evenings of
// the start day plus early mornings of the following day.
type Schedule struct {
Start, End time.Duration // minutes-since-midnight in Loc
Loc *time.Location
WeekdaysOnly bool
}
// NewSchedule parses the window out of the [quota] config fields.
func NewSchedule(peakStart, peakEnd, tzName string, weekdaysOnly bool) (Schedule, error) {
start, err := config.ParseHHMM(peakStart)
if err != nil {
return Schedule{}, err
}
end, err := config.ParseHHMM(peakEnd)
if err != nil {
return Schedule{}, err
}
loc, err := time.LoadLocation(tzName)
if err != nil {
return Schedule{}, err
}
return Schedule{Start: start, End: end, Loc: loc, WeekdaysOnly: weekdaysOnly}, nil
}
// SameDay reports whether t is inside the window without crossing midnight
// (start <= t < end, single-day window).
func (s Schedule) inWindow(mins time.Duration) bool {
if s.Start <= s.End {
return mins >= s.Start && mins < s.End
}
// Wrapped window: [start, 24h) of the start day, [0, end) of the next.
return mins >= s.Start || mins < s.End
}
// InPeak reports whether t falls inside the peak window, evaluated in the
// schedule's timezone. For wrapped windows the weekday check applies to the
// day the window STARTED on (a Sunday 22:00-02:00 window is off all week
// when weekdays-only, because it starts on Sunday).
func (s Schedule) InPeak(t time.Time) bool {
local := t.In(s.Loc)
mins := time.Duration(local.Hour())*time.Hour + time.Duration(local.Minute())*time.Minute
if s.Start <= s.End {
if !s.inWindow(mins) {
return false
}
return !s.WeekdaysOnly || isWeekday(local)
}
// Evening half: today carries the window.
if mins >= s.Start {
return !s.WeekdaysOnly || isWeekday(local)
}
// Morning half: the window started yesterday.
if mins < s.End {
return !s.WeekdaysOnly || isWeekday(local.AddDate(0, 0, -1))
}
return false
}
func isWeekday(t time.Time) bool {
wd := t.Weekday()
return wd >= time.Monday && wd <= time.Friday
}