Skip to content

fix(quota): resolve Quota Sharing plan from pool's primary connection - #14042

Merged
diegosouzapw merged 1 commit into
release/v3.8.51from
fix/13876-quota-share-consumed
Sep 18, 2026
Merged

diegosouzapw merged 1 commit into
release/v3.8.51from
fix/13876-quota-share-consumed

Conversation

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Root cause

Multi-connection Quota Sharing pools resolve a DIFFERENT provider plan depending on which member connection actually served a request (write path) vs. the pool's primary connection (dashboard read path). The wizard's "Limite" step PUTs a manual plan override only to the primary connection (connectionIds[0]); any other pool member falls back to a different (catalog/empty) plan shape. Since the quota_consumption dimension key is poolId:unit:window, a different unit/window means recordConsumption() writes to a different bucket than the one the dashboard's usage route reads — real traffic never appears as "consumed" even though it genuinely happened.

Fix

  • src/lib/quota/enforce.ts::enforceQuotaShare — resolve the plan from pool.connectionId (the pool's canonical primary connection) instead of input.connectionId (the connection that actually served the request).
  • src/lib/quota/enforce.ts::recordConsumption — keep the matched QuotaPool object (not just its id) from the pool-search loop, then resolve the plan from matchedPool.connectionId for the same reason.
  • getSaturation(input.connectionId, ...) is left untouched — that signal is legitimately per-connection.

Regression tests

  • tests/unit/quota-share-multiconn-plan-mismatch.test.ts — RED before the fix (AssertionError: dashboard should show the 5000 tokens actually consumed via conn-secondary, got 0 — 0 !== 5000), GREEN after.
  • tests/unit/quota-share-multiconn-enforce-cap.test.ts — companion test proving a cap configured on the primary connection's plan is now enforced for a request served by a non-primary pool member (also confirmed RED before / GREEN after during development).
node --import tsx/esm --test tests/unit/quota-share-multiconn-plan-mismatch.test.ts tests/unit/quota-share-multiconn-enforce-cap.test.ts
# tests 2, pass 2, fail 0

Gates run

  • node scripts/check/check-file-size.mjs — no violation on touched files.
  • node scripts/check/check-complexity.mjs — OK (2857 ≤ 3218 baseline).
  • node scripts/check/check-cognitive-complexity.mjs — OK (1291 ≤ 1437 baseline).
  • npm run typecheck:core — exit 0.
  • npx eslint --suppressions-location config/quality/eslint-suppressions.json <changed files> — clean.
  • node scripts/check/check-changelog-integrity.mjs — OK.
  • Existing quota regression suite re-run and green (58 + 25 tests): quota-sqlite-store, quota-pool-usage-equal-split, quota-pool-usage-summed-budget, quota-enforce-await-store, quota-enforce, quota-equal-split, quota-summed-budget, quota-multiprovider, quota-per-key-model, quota-per-key-model-hotpath, quota-spend-recorder, combo-quota-soft-penalty, quota-epsilon-unconfigured-allow, serial/quota-division-blocks, quota-group-allocations.

Closes #13876

⚠️ base-red inherited: #14004 — docs env/docs contract (fixed separately in #14022), chatHelpers file-size drift

Multi-connection Quota Sharing pools resolve a DIFFERENT provider plan
depending on which member connection actually served a request (write
path, enforceQuotaShare/recordConsumption) vs. the pool's primary
connection (dashboard read path, /api/quota/pools/[id]/usage). The
wizard's "Limite" step PUTs a manual plan override only to the primary
connection, so any other pool member fell back to a different
(catalog/empty) plan shape. Since the quota_consumption dimension key
is poolId:unit:window, a different unit/window meant recordConsumption
wrote to a bucket the dashboard never read, so real traffic served via
a non-primary connection never appeared as "consumed".

Fix: resolve the plan from the pool's canonical primary connection
(pool.connectionId) in both enforceQuotaShare and recordConsumption,
matching the dashboard's read path. recordConsumption now keeps the
matched pool object (not just its id) so it can reach connectionId.
getSaturation(input.connectionId, ...) is untouched — that signal is
legitimately per-connection.
@diegosouzapw

Copy link
Copy Markdown
Collaborator Author

Validated in local merge-train /tmp/mt-train3b.log on 192.168.0.113 @ train tip 408e2128791696a18966681953136fc96aeb99b0 (32 PRs boarded): static gates green; full test:unit 40694 tests, 17 failing — every one reproduces on the pure release tip (base-red sweep list), zero new reds. Merged --admin per merge-gates §4/§7.

@diegosouzapw
diegosouzapw merged commit 0d31fd3 into release/v3.8.51 Sep 18, 2026
14 of 21 checks passed
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…rence#13876) (cheaper-inference#14042)

Multi-connection Quota Sharing pools resolve a DIFFERENT provider plan
depending on which member connection actually served a request (write
path, enforceQuotaShare/recordConsumption) vs. the pool's primary
connection (dashboard read path, /api/quota/pools/[id]/usage). The
wizard's "Limite" step PUTs a manual plan override only to the primary
connection, so any other pool member fell back to a different
(catalog/empty) plan shape. Since the quota_consumption dimension key
is poolId:unit:window, a different unit/window meant recordConsumption
wrote to a bucket the dashboard never read, so real traffic served via
a non-primary connection never appeared as "consumed".

Fix: resolve the plan from the pool's canonical primary connection
(pool.connectionId) in both enforceQuotaShare and recordConsumption,
matching the dashboard's read path. recordConsumption now keeps the
matched pool object (not just its id) so it can reach connectionId.
getSaturation(input.connectionId, ...) is untouched — that signal is
legitimately per-connection.
@diegosouzapw
diegosouzapw deleted the fix/13876-quota-share-consumed branch October 18, 2026 23:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(backend): quota-share dashboard consumed amount does not update (needs repro)

1 participant