maxpool 1.8.0 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maxpool",
3
- "version": "1.8.0",
3
+ "version": "1.8.2",
4
4
  "description": "Multi-account Claude Code proxy with adaptive, rate-aware load balancing across Claude accounts",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -1,5 +1,9 @@
1
1
  import { refreshAccessToken, isTokenExpiringSoon, modelFamily, tokenFingerprint } from './oauth.js';
2
2
  import { CapacityLedger } from './capacity-ledger.js';
3
+
4
+ // A capacity window boundary must move by at least this much to count as a real
5
+ // window ADVANCE rather than reset-stamp jitter (see noteCapacityWindowAdvance).
6
+ const WINDOW_ADVANCE_EPSILON_MS = 60_000;
3
7
  import { peakWindowState, DEFAULT_PEAK_CAP } from './peak-window.js';
4
8
 
5
9
  // Bounded re-poll hold for an account blocked ONLY by a transient, self-clearing
@@ -3050,8 +3054,21 @@ export class AccountManager {
3050
3054
  /** Close a cycle because a probe observed the window ADVANCE (a new reset stamp) —
3051
3055
  * covers the case where the old stamp was never learned. */
3052
3056
  noteCapacityWindowAdvance(accountName, window, prevResetAt, nextResetAt) {
3053
- if (!prevResetAt || !nextResetAt || nextResetAt <= prevResetAt) return;
3054
- this.capacity.closeCycle(accountName, window, prevResetAt, { resetAt: prevResetAt });
3057
+ if (!prevResetAt || !nextResetAt) return;
3058
+ // TWO guards, both learned from live data (2026-08-23):
3059
+ // 1. PAST stamp = a probe that answered late (its window rolled mid-request) or
3060
+ // vendor clock skew — honoring it closed a minutes-long "cycle" sliver. Close
3061
+ // at NOW instead: the window genuinely rolled, just later than the stale stamp.
3062
+ // 2. JITTER: OAuth stamps derive per-response as Date.now()+delay*1000
3063
+ // (parseResetHeader), so one boundary reads ~2s later on every response; a
3064
+ // bare `>` comparison shredded one real 5h window into 9-10 fake cycles and
3065
+ // dated a "weekly" cycle a week into the future. A real advance moves a whole
3066
+ // window (>=5h) — the 60s epsilon separates it by three orders of magnitude.
3067
+ // Provider stamps (z.ai/Kimi probe) are absolute and never jitter.
3068
+ const nowMs = Date.now();
3069
+ const boundary = nextResetAt <= nowMs ? nowMs : nextResetAt;
3070
+ if (boundary - prevResetAt < WINDOW_ADVANCE_EPSILON_MS) return;
3071
+ this.capacity.closeCycle(accountName, window, boundary, { resetAt: prevResetAt });
3055
3072
  }
3056
3073
 
3057
3074
  /**
@@ -15,7 +15,15 @@
15
15
  * Pre-mortem (2026-08-22) blockers B1/B2 + majors M3-M7 are the load-bearing comments.
16
16
  */
17
17
 
18
- const SCHEMA_VERSION = 1;
18
+ // v2 (2026-08-23): v1 histories are POISONED and are deliberately dropped on load.
19
+ // The OAuth reset-stamp jitter (see AccountManager.noteCapacityWindowAdvance) shredded
20
+ // real windows into slivers and recorded future-dated weekly cycles, so a v1 payload's
21
+ // averages are wrong for weeks. Starting empty costs one window; keeping it costs trust.
22
+ const SCHEMA_VERSION = 2;
23
+
24
+ // Two closes this far apart are the SAME boundary observed twice (a clock-close and a
25
+ // stamp-advance racing across the boundary second), not two windows.
26
+ const SAME_BOUNDARY_MS = 5_000;
19
27
  const MAX_CYCLES_PER_WINDOW = 50;
20
28
  const MAX_DAY_BUCKETS = 10;
21
29
 
@@ -134,8 +142,13 @@ export class CapacityLedger {
134
142
  // one that drags every average down. A LATER window reporting the same numeric stamp
135
143
  // value (clock coincidence) is distinguished by endedAt. Pinned by I3.
136
144
  const prev = rec[window].closed[rec[window].closed.length - 1];
137
- if (resetAt != null && prev && prev.resetAt === resetAt && prev.endedAt === endedAt
138
- && open.complete && !open.disabledDuring) {
145
+ // Same boundary within a few seconds, not just byte-identical stamps: the two
146
+ // closers can observe one rollover through slightly different stamps (jitter), and
147
+ // an exact-match-only fold then admitted a 0.2-minute sliver as its own cycle.
148
+ const sameBoundary = resetAt != null && prev
149
+ && Math.abs((prev.resetAt ?? prev.endedAt) - resetAt) <= SAME_BOUNDARY_MS
150
+ && Math.abs(prev.endedAt - endedAt) <= SAME_BOUNDARY_MS;
151
+ if (sameBoundary && open.complete && !open.disabledDuring) {
139
152
  // Fold ONLY a complete tail: folding a partial/disabled tail would flip the
140
153
  // flags on the prior legitimate observation and ERASE it from the averages
141
154
  // (round 3, RT3-2) — strictly worse than leaving a tiny excluded cycle.