From 70619a8d0b8c4e79e6d8890253f3fc8dbefc437f Mon Sep 17 00:00:00 2001 From: barckcode Date: Thu, 10 Sep 2026 21:33:39 +0100 Subject: [PATCH 1/2] docs(limits): record that the published 1M is a rounded-down 1,048,576 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rate-limits test carries a contract: "If any of them moves upstream, this test has to be updated in the same change: the failure is the point." The GLM context window is moving upstream (cloud-api 500,000 -> 1,048,576), so this is that same change. The published value does NOT move, and that is the point of the commit. It already reads 1,000,000 here while cloud-api still says 500,000, so the mirror was ahead of its source and nothing recorded why. Now it does: * 1,000,000 is the ROUNDED-DOWN form of the backend's 1,048,576, not a stale copy of it; * rounding DOWN is the safe direction — a member who trusts 1M can always send it, whereas advertising 1.049M and enforcing less could not be honoured; * the exact value renders as "1,049M" under es-ES, which reads as 1049 million, so publishing it would be worse than imprecise. The test note also states the condition that ends this: if the backend ever drops BELOW 1,000,000, rounding down stops being conservative and this has to move with it. `npm run build` clean; vitest 727 passed across 50 files. Co-Authored-By: Claude Opus 5 --- src/lib/rateLimits.ts | 7 +++++++ src/tests/lib/rateLimits.test.ts | 10 +++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/lib/rateLimits.ts b/src/lib/rateLimits.ts index 95359a2..b1a1c3f 100644 --- a/src/lib/rateLimits.ts +++ b/src/lib/rateLimits.ts @@ -65,6 +65,13 @@ export const DEFAULT_RATE_LIMITS: RateLimitsConfig = { // mirror the backend policy (cloud-api modelRateLimits + the token cap for // glm5.3) and the usage hook's window budget, which is the same set of // numbers the member portal publishes. + // + // contextTokens is the one that is NOT an exact mirror: the backend carries + // 1,048,576 (raised from 500,000 on 2026-09-10, and exactly what the Novita + // primary serves) and this publishes the rounded-down 1,000,000. Rounding + // DOWN is the safe direction — a member who trusts 1M can always send it — + // and the exact value renders as "1,049M" in es-ES, which reads as 1049 + // million. See the note in rateLimits.test.ts. windowedModels: [ { model: 'glm5.3', diff --git a/src/tests/lib/rateLimits.test.ts b/src/tests/lib/rateLimits.test.ts index 13cf237..90a7f18 100644 --- a/src/tests/lib/rateLimits.test.ts +++ b/src/tests/lib/rateLimits.test.ts @@ -16,7 +16,15 @@ import { * were the ones that do not apply to them. These asserts pin the four numbers * to what the platform actually enforces: * - * context 1,000,000 cloud-api usage_quota.go modelRateLimits + * context 1,000,000 the ROUNDED-DOWN form of cloud-api's 1,048,576 + * (usage_quota.go modelRateLimits). Deliberately not + * the exact value: `formatTokens` would render it + * "1,049M" in es-ES, which reads as 1049 million, and + * publishing the lower number is the safe direction — + * a member who believes 1M can always send it, while + * advertising 1.049M and enforcing less could not be + * honoured. If the backend ever drops BELOW 1,000,000 + * this stops being conservative and must move. * concurrency 5 idem, and the ratelimit hook * 400M per rolling 4h ratelimit hook ROLLING_WINDOW_S / rolling budget * 3,000M per period cloud-api usage_quota.go monthlyTokenCaps From 4286bca27c760fdc900dfa31a2163e9035a03cf5 Mon Sep 17 00:00:00 2001 From: barckcode Date: Thu, 10 Sep 2026 22:48:01 +0100 Subject: [PATCH 2/2] fix(limits): publish the exact 1,048,576 and round only the display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reworked after the QA review, which took apart the reasoning in my first attempt and was right on both counts. I had published a rounded-down 1,000,000 on the grounds that the exact value renders "1,049M" in es-ES and "reads as 1049 million". It does not: in es-ES the comma is the DECIMAL separator, as this file's own comment says two lines above ("the card cannot read '3,000M' next to a model card that says '3.000M'"). A Spanish reader reads 1,049M as ~1 million. My premise was wrong. The real defect was the juxtaposition — "1,049M" beside "3.000M" on the same page, a comma and a dot meaning opposite things in the same units — and that belongs to the FORMATTER, not to the published number. `maximumFractionDigits: 0` renders exactly the round "1M" while publishing the true value: 1048576 es: 1M en: 1M 3000000000 es: 3.000M en: 3,000M WHAT ROUNDING THE CONSTANT WOULD HAVE COST, which is the part that convinced me: the site would sit permanently 4.8% below the source it declares it mirrors, and the test contract would mutate from an EQUALITY into a floor. The equality is the mechanism — it is what makes a backend change fail here instead of shipping quietly, and it is exactly what caught this whole class of bug. A floor is weaker: a future 900_000 upstream would pass it green. So the test note goes back to the one-line mirror it was, and the assert is an equality again. `npm run build` clean; vitest 727 passed across 50 files. Co-Authored-By: Claude Opus 5 --- src/lib/rateLimits.ts | 26 ++++++++++++++++++-------- src/tests/lib/rateLimits.test.ts | 12 ++---------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/lib/rateLimits.ts b/src/lib/rateLimits.ts index b1a1c3f..21ad93e 100644 --- a/src/lib/rateLimits.ts +++ b/src/lib/rateLimits.ts @@ -66,16 +66,17 @@ export const DEFAULT_RATE_LIMITS: RateLimitsConfig = { // glm5.3) and the usage hook's window budget, which is the same set of // numbers the member portal publishes. // - // contextTokens is the one that is NOT an exact mirror: the backend carries - // 1,048,576 (raised from 500,000 on 2026-09-10, and exactly what the Novita - // primary serves) and this publishes the rounded-down 1,000,000. Rounding - // DOWN is the safe direction — a member who trusts 1M can always send it — - // and the exact value renders as "1,049M" in es-ES, which reads as 1049 - // million. See the note in rateLimits.test.ts. + // contextTokens mirrors the backend EXACTLY: 1,048,576, raised from 500,000 + // on 2026-09-10 and exactly what the Novita primary serves. It renders as + // "1M" because formatTokens rounds the display, which is the layer that + // should do it — publishing a rounded 1,000,000 here would leave the site + // 4.8% below the source it claims to mirror, and would turn the test below + // from an equality into a floor. The equality is the mechanism: it is what + // makes a backend change fail here instead of shipping quietly. windowedModels: [ { model: 'glm5.3', - contextTokens: 1_000_000, + contextTokens: 1_048_576, maxParallel: 5, windowHours: 4, windowTokens: 400_000_000, @@ -96,7 +97,16 @@ export function formatTokens(tokens: number, lang: DocsLocale = 'en'): string { // cannot read "3,000M" next to a model card that says "3.000M". // `useGrouping: 'always'` because es-ES leaves four-digit numbers ungrouped, // which would print 3000M beside a model card that already says 3.000M. - const fmt = new Intl.NumberFormat(lang === 'es' ? 'es-ES' : 'en-US', { useGrouping: 'always' }); + // `maximumFractionDigits: 0` so a window of 1,048,576 prints "1M" and not + // "1,049M". Without it the page shows a decimal comma (1,049M) next to a + // thousands dot (3.000M) in es-ES — both correct, and confusing side by + // side. Rounding the DISPLAY is the right layer: the published constant + // stays equal to the backend, so the test below can keep asserting + // equality rather than a floor. + const fmt = new Intl.NumberFormat(lang === 'es' ? 'es-ES' : 'en-US', { + useGrouping: 'always', + maximumFractionDigits: 0, + }); if (tokens >= 1_000_000) return `${fmt.format(tokens / 1_000_000)}M`; if (tokens >= 1_000) return `${fmt.format(tokens / 1_000)}K`; return String(tokens); diff --git a/src/tests/lib/rateLimits.test.ts b/src/tests/lib/rateLimits.test.ts index 90a7f18..3bc56ea 100644 --- a/src/tests/lib/rateLimits.test.ts +++ b/src/tests/lib/rateLimits.test.ts @@ -16,15 +16,7 @@ import { * were the ones that do not apply to them. These asserts pin the four numbers * to what the platform actually enforces: * - * context 1,000,000 the ROUNDED-DOWN form of cloud-api's 1,048,576 - * (usage_quota.go modelRateLimits). Deliberately not - * the exact value: `formatTokens` would render it - * "1,049M" in es-ES, which reads as 1049 million, and - * publishing the lower number is the safe direction — - * a member who believes 1M can always send it, while - * advertising 1.049M and enforcing less could not be - * honoured. If the backend ever drops BELOW 1,000,000 - * this stops being conservative and must move. + * context 1,048,576 cloud-api usage_quota.go modelRateLimits * concurrency 5 idem, and the ratelimit hook * 400M per rolling 4h ratelimit hook ROLLING_WINDOW_S / rolling budget * 3,000M per period cloud-api usage_quota.go monthlyTokenCaps @@ -33,7 +25,7 @@ import { * change: the failure is the point. */ const GLM = { - contextTokens: 1_000_000, + contextTokens: 1_048_576, maxParallel: 5, windowHours: 4, windowTokens: 400_000_000,