Repository navigation
Description
Finding
isQuotaPool (pm-stack/aggregator/src/feed.ts:321-334) — the gate whose doc comment promises "One quota pool whose own shape is safe to hand to the renderers (#2429)" — validates a pool's credential rows only as records holding a windows array, and never checks activeSessions at all. sanitizeQuotaView (feed.ts:392-408) filters credential-row windows and pool windows, but passes credential label/freshness and every activeSessions entry through untouched. renderQuota then dereferences both unguarded, so one malformed row or session entry that no producer emits crashes the whole /quota render instead of dropping at the boundary like its sibling fields do (#2429's drop-and-count pattern).
The QuotaCredentialRow contract (model.ts:269-282) requires label: string, providerId: string, and a required freshness: PoolFreshness (measuredAt/source/state). The only producer, credentialRows (quota-current.ts:195-214), always emits all three. activeSessions (model.ts:256) is { session: string; model: string; tokens: number }[]; the collector (scripts/collect-fleet-feed.ts:580-587) always emits that shape.
Evidence (main 33aefa7, verified this run)
- feed.ts:326-331 — credentials check is only
isRecord(row) && Array.isArray(row.windows); nolabel,providerId, orfreshnesscheck.activeSessionsis never mentioned in the gate. - feed.ts:399-406 —
sanitizeQuotaViewmaps credential rows replacing onlywindows; a row's missing/nullfreshnesssurvives sanitization. - render.ts:2045-2048 —
c.freshness.state === "ok",esc(c.freshness.state),c.freshness.errordereferenced unguarded on every credential row. - render.ts:2035-2040 —
(p.activeSessions ?? []).map((s) => … s.tokens.toLocaleString()): a non-array value, anullelement, or an element withouttokensall throw. - Laptop Bun probe (~/git/fleet/probe-2026-11-01-laneB-credrows/, real feed.ts/render.ts/model.ts copied from the laptop primary at 33aefa7; sha256 feed.ts d62b3096…, render.ts 061fc8ad…, model.ts f987be93… — identical to sandbox main; control pool with a well-formed credential row + active session renders OK, 25,787 bytes):
credentials: [{ windows: [] }](no label/providerId/freshness) → gatetrue, droppedPools=0,renderQuotathrowsTypeError: undefined is not an object (evaluating 'c.freshness.state')credentials: [{ …, freshness: null }]→ gatetrue, throwsTypeError: null is not an object (evaluating 'c.freshness.state')credentials: [{ …, freshness: "ok" }](string) → gatetrue, renders — the row's state silently renders blank (falsified, no crash)activeSessions: [null]→ gatetrue, throwsTypeError: null is not an object (evaluating 's.session')activeSessions: "s1"→ gatetrue, throwsTypeError: (p.activeSessions ?? []).map is not a functionactiveSessions: [{ session: "s1", model: "gpt" }](notokens) → gatetrue, throwsTypeError: undefined is not an object (evaluating 's.tokens.toLocaleString')activeSessions: [{ …, tokens: "5000" }]→ gatetrue, renders the string verbatim (no crash; type falsified)
Why it matters
/quota is the fleet's quota page; its feed is a hand-/script-produced JSON document, exactly the input the #2429 gate-and-sanitize boundary exists to fail soft against. Every sibling surface in the same pool — windows, burn segments, charges, subscriptions — drops malformed elements individually and counts the drops. Credential rows and active sessions are the two remaining unguarded dereferences in the same renderer: one bad row takes the whole page down (and the unsanitized shape is also served verbatim by /api/quota.json) instead of losing one row.
Acceptance criteria
- A pool whose credential rows lack a string
label/providerIdor a recordfreshnesswith a validstate, or whoseactiveSessionsis not an array of{ session: string, model: string, tokens: finite number }, no longer crashesrenderQuota; the owning layer is pinned (extendisQuotaPoolvs drop-and-count insanitizeQuotaView, following the aggregator(feed): isFleetFeed checks only that quota.pools is an array — burn/choices, pool entries and windows unvalidated, one malformed pool crashes /quota #2429 pattern) and applied consistently to both surfaces, with drops counted/surfaced where the sanitizer owns them. - A well-formed pool with credential rows and active sessions (existing fixtures/tests) renders unchanged.
- Regression tests cover at least: credential row without
freshness,freshness: null,activeSessions: [null], a non-arrayactiveSessions, and a session entry withouttokens.
Dedup: #2429 (closed) built the pool/window gate and sanitizer — its credential check stopped at record+windows and it never touched activeSessions. #3427/#3428 cover quota window/burn fields, #3513/#3458 subscriptions/charges, #3897/#2417 the orchestration section — different fields in different gates. Searches for "isQuotaPool" and "activeSessions" across open and closed issues return no covering issue.
Activity
dezren39 commentedon Nov 1, 2026
🤖 Agent note · filed
38 remaining items
dezren39 commentedon Nov 4, 2026
🤖 Agent note · picked up
dezren39 commentedon Nov 4, 2026
🤖 Agent note · done
fix(aggregator): sanitize quota credential/session rows). The issue body is stale relative to that merge; no second patch needed.02a3b9559b3cb3293924eca155267e8d3d493a70, an ancestor of currentorigin/main373d23bbe79670b0fc769d78260fc4b978bb3ad9. The PR validates credential label/providerId/freshness and active-session shapes, drops/counts malformed rows, and reports 126 focused tests passing. Current-mainfeed.tsandfeed.test.tscontain the sanitizer and malformed-shape regressions.already_done; issue aggregator(feed): isQuotaPool never checks credential-row label/freshness or activeSessions — a windows-only credential row or a null session crashes renderQuota #3921 remains OPEN pending issue-owner closure. No branch or PR created.developing-today commentedon Nov 8, 2026
state: handed_off
queue: repo-health-code-pilot
task: 12132 (triage)
by: lane code-k (worker repo-worker-code)
Picked up and revalidated fresh: issue #3921 is OPEN, no hard-stop labels (
held,user/owned,do-not-merge,do-not-auto-editabsent). Execution-lane assignment returnedopencode— handed off to the laptop opencode claimant, which launches the bound session that drives task 12132 to its terminal state. This lane does not work it in parallel.dezren39 commentedon Nov 8, 2026
Partial verification — staying open (2026-11-07 done-task-only audit, tracking: #7016).
Queue task(s) [5876, 6237, 8295] were marked done, and some work did land:
No merged change closes this issue's full scope, so the done status is not treated as completion. Remainder re-queued as triage task 11683.
dezren39 commentedon Nov 8, 2026
Handed off to opencode claimant: task 12132 claimed by lane code-e, execution lane assigned
opencode. The claimant launches the bound opencode session for issue #3921; this lane does not work it directly.