Repository navigation
Description
Problem
The reader side of the quota-current contract never range-checks pctOfLimit, so a finite-but-impossible percent in a fresh state:"ok" gatherer read is applied verbatim to the pool — and steers placement:
pctWindows(pm-stack/aggregator/src/quota-current.ts:88-97) gates only ontypeof w.pctOfLimit === "number" && Number.isFinite(w.pctOfLimit)(:90) and then copies the value verbatim intousedandpercentagainst a hardcodedlimit: 100(:95-96). There is no [0,100] check.applyEntry(quota-current.ts:118+) installs those windows on the pool and recomputespool.state = poolState(pool);poolState(src/derive.ts:164-168) returns"walled"when any window percent is >= 100, andoverlayQuotaCurrentthen recomputescomputeChoices— so one glitched read at 150% marks a healthy pool walled and lands it indoNotStart, steering new work away from a pool that is actually fine. A read at -20% publishes a negative percent window that renders as negative usage.overlayTursoUsage(quota-current.ts:225) is weaker still:...(w.pctOfLimit != null ? { percent: w.pctOfLimit } : {})— no type or finite check at all, so any non-null value (150, -20, a string) becomes the Turso metric'spercent.
Evidence (verified this run on main 3a425552)
Laptop Bun probe importing the real quota-current.ts (aggregator src/ copied verbatim to the laptop probe dir ~/git/fleet/probe-2026-10-30-laneA-quotacurrent/, run with bun probe.ts against a one-pool view):
- Fresh ok entry, window
pctOfLimit: 150→ pool state"walled", window{used: 150, percent: 150, limit: 100}, andchoices.doNotStart: ["anthropic:claude-pro"]— the healthy pool is excluded from placement by a single out-of-range read. - Fresh ok entry, window
pctOfLimit: -20→ pool state"healthy"with windowpercent: -20published as-is. - Control: the module's own tests show in-range reads overlay normally — the defect is only the missing range gate at this reader.
Why it matters
quota-current.json is written every 15 minutes by a gatherer on another host and embedded into the fleet feed by the collector; this reader is the trust boundary for that file (the same rationale as #2416's shape gate). #2571 pins the writer-side mappers in quota-gather-map.ts, but the reader must not depend on every present and future writer being correct: a stale gatherer build, a hand-edited file, or a new provider adapter with a percent bug currently reaches pool state and placement choices unchecked. The failure is also silent — the pool simply reads walled (or negative), with freshness stamped ok.
Acceptance criteria
-
pctWindowsnever emits a window whose percent is outside [0,100] from a gatherer read (treatment pinned at triage: drop the window — the function's existing pattern for unusable pct — or clamp; sibling in-range windows of the same entry still apply). -
overlayTursoUsageonly forwards apercentthat is a finite number in [0,100]; other values omitpercentrather than passing through. - Regression tests in test/quota-current.test.ts pin: 150 and 1e9 do not wall the pool nor enter
doNotStart; -20 never publishes as a window percent; in-range reads (including exactly 0 and exactly 100) overlay unchanged. - Existing quota-current / quota tests stay green.
Dedup
- aggregator(quota-gather-map): entryFromResult and entryFromFileExport never range-check percent — a window at -20% or 1e9% publishes as live ok data and appends as pct history against limit:100 #2571 (OPEN) is the writer side:
entryFromResult/entryFromFileExportin quota-gather-map.ts. Its packet names quota-current.ts:90-96 as a downstream flow-through, but its acceptance pins only the mappers — no reader-side gate is tracked anywhere. - aggregator(quota-current): parseQuotaCurrent never checks windows entries — one null entry crashes the whole gatherer overlay and provenance still claims it applied #2416 (OPEN) is this file's shape gate (null/non-object window entries crash the overlay) — different failure: a well-formed numeric 150 passes every shape check.
- aggregator(snapshot-records): recordsFromProviderUsage never range-checks used_percent — a Codex window at -20% or 1e9% is appended as measured pct history against its own limit:100 #2568 (OPEN) is
recordsFromProviderUsagein snapshot-records.ts; aggregator(quota-current): stale-path newest pick is not finite-gated — a garbage or far-future measuredAt wins the pool's displayed freshness #2253 (OPEN) is the stale-pathmeasuredAtpick in this file — both distinct. - Searched open + recently closed issues for
quota-current pctOfLimit,parseQuotaCurrent,overlayQuotaCurrentthis run: no range-check issue for the reader side.
Activity
dezren39 commentedon Oct 30, 2026
🤖 Agent note · filed
pctWindows(quota-current.ts:90) gates pctOfLimit finite-only and copies it verbatim into used/percent against limit:100, so a fresh ok read at 150% recomputes the pool to walled and into choices.doNotStart, and -20% publishes as negative usage;overlayTursoUsage(:225) forwards any non-null pctOfLimit as percent with no check at all. Verified with the real module on the laptop (main 3a42555).4 remaining items
dezren39 commentedon Nov 2, 2026
🤖 Agent note · picked up
Merge pull request #4214 from developing-today/queue/5384-2582-usable…
dezren39 commentedon Nov 2, 2026
🤖 Agent note · done