maxpool 1.8.0 → 1.8.1

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.1",
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,7 +3054,19 @@ 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;
3057
+ if (!prevResetAt || !nextResetAt) return;
3058
+ // EPSILON, not `>`. An OAuth reset stamp is derived per-response as
3059
+ // `Date.now() + delay_seconds * 1000` (parseResetHeader), so the SAME window
3060
+ // boundary reads a little later on every response — sub-second to ~2s of jitter.
3061
+ // A bare `nextResetAt > prevResetAt` fired the advance-close on each of those,
3062
+ // shredding one real 5h window into 9-10 fake cycles and closing a "weekly"
3063
+ // cycle whose endedAt was a week in the FUTURE. Measured on live state.json
3064
+ // 2026-08-23, 12h after v1.8.0 shipped: mk@dubner.io had 9 ses cycles between
3065
+ // 01:00 and 06:00, the shortest 0.2 minutes. A REAL advance is a whole window
3066
+ // (>=5h); 60s separates the two by three orders of magnitude.
3067
+ // Provider stamps (z.ai/Kimi probe) are absolute and did NOT jitter — which is
3068
+ // how the defect localized to the OAuth path.
3069
+ if (nextResetAt - prevResetAt < WINDOW_ADVANCE_EPSILON_MS) return;
3054
3070
  this.capacity.closeCycle(accountName, window, prevResetAt, { resetAt: prevResetAt });
3055
3071
  }
3056
3072
 
@@ -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.