Repository navigation
Description
Problem
The #3921 sanitization added in PR #4508 (merged today, main c84bbcfa1) validates quota credential rows and active sessions by shape in pm-stack/aggregator/src/feed.ts — but three value/pool-level gaps remain in the same sanitizeQuotaView pass, all verified this run:
- Pool-level
freshnessis never sanitized at all.isQuotaPool(feed.ts:473-480) does not look atpool.freshness, andsanitizeQuotaView(feed.ts:596-625) rewrites onlywindows,credentials, andactiveSessions.isQuotaFreshnessexists (feed.ts:486-495) but is applied only inside credential rows. So a pool carryingfreshness: "error"(a bare string) orfreshness: { measuredAt: "2026-02-30T00:00:00Z", source: "quota-current", state: "banana" }survives sanitization untouched and renders inrenderQuota(render.ts:2278-2280) as an empty/bogus "gatherer · · measured — ·" line or a literalbananastate; the health error count in render.ts:3306 (pool.freshness?.state === "error") also misses every malformed form. The model'sQuotaPool.freshnessisPoolFreshness(model.ts:257) — the same shape credential rows are now dropped for failing. - Active-session
tokensis finite-only.isQuotaActiveSession(feed.ts:505-512) usesisFiniteNumber(v.tokens), so a cumulative token count of-12345passes and renders asburning: s-neg (gpt-5) -12,345 tok(render.ts:2262-2267). Every sibling numeric guard in the same section is non-negative for exactly this reason: windowused/limit(aggregator(feed): isQuotaWindow accepts any string as resetsAt and any finite used/limit/percent — an impossible reset date is clocked as Mar 2 in guidance, a -50% window reads healthy and a 15000% window walls a pool #3427,isNonNegative), burn-segmenttokens(aggregator(feed): isBurnSegment accepts negative tokens, non-date from/to and inverted ranges — garbage burn rows survive sanitizeQuotaView and render as measured history #3428,isNonNegative). - Credential-row freshness
measuredAtis never date-checked.isQuotaFreshnessaccepts any string, so a credential row withfreshness.measuredAt: "banana"is kept withdroppedCredentials: 0, while windowresetsAtand burnfrom/toin the same file must passisIsoDate(real calendar dates — "2026-02-30" fails). The sanitized view is projected publicly via/api/quota.json, so the bogus stamp reaches consumers as if measured.
Evidence (verified this run, laptop probe)
Probe: ~/git/fleet/probe-2026-11-02-laneA-quotapool/probe.test.ts on the laptop, importing the real feed.ts/render.ts at main c84bbcfa1 (feed.ts md5 0d344ffcc96d83587ae2aa511da23c1e, render.ts md5 93546815e6efb4e2530a05de67c991aa, identical on sandbox and laptop clones). bun test: 6/6 pass, documenting the current (buggy) behavior:
- P1: session
tokens: -12345→ kept,droppedActiveSessions: 0, HTML contains-12,345 tok. - P2: pool
freshness: "error"→ kept verbatim,droppedPools: 0, HTML contains the emptygatherer · · measured —line. - P3: pool freshness
{measuredAt: "2026-02-30T00:00:00Z", state: "banana"}→ kept verbatim, HTML rendersbanana. - P4: credential row
freshness.measuredAt: "banana"→ kept,droppedCredentials: 0. - P5: pool
burnTokensPerMin: -500→ kept and renders-500 tok/min(same unsanitized pool-scalar pattern; render.ts:2281 interpolates it unchecked). - C1 control: a well-formed pool (valid freshness, session
tokens: 42) passes sanitization unchanged with zero drops — the guards above are the only gap.
Why it matters
sanitizeQuotaView is the feed boundary whose contract (validate.ts header, #2576) is that no consumer, store append, or render sees unvalidated values. #3921 closed the crash class for credential/session shapes; the pool's own freshness stamp — the field that tells Drew whether a pool's numbers are current or walled — still passes through in any shape, and negative cumulative counts render as measured fact on the quota page and in the public /api/quota.json projection.
Acceptance criteria
-
sanitizeQuotaViewvalidates pool-levelfreshnesswith the sameisQuotaFreshnessguard used for credential rows: a present-but-malformed pool freshness is dropped from the pool (pool itself survives, like the non-arrayactiveSessionstreatment) and the loss is surfaced in the dropped counts (extend the counts shape or document the chosen bucket). -
isQuotaFreshnessrequiresmeasuredAtto be a real ISO calendar date (isIsoDate), for both pool and credential-row freshness. -
isQuotaActiveSessionrequirestokensto be non-negative (isNonNegative), consistent with windowusedand burntokens; negative-token sessions drop individually and count indroppedActiveSessions. - Pool
burnTokensPerMin, when present, is validated as a non-negative finite number or dropped from the sanitized pool. - New regression tests in
pm-stack/aggregator/test/feed.test.tscovering P1–P5 above; the well-formed control (C1) and all existing aggregator(feed): isFleetFeed checks only that quota.pools is an array — burn/choices, pool entries and windows unvalidated, one malformed pool crashes /quota #2429/aggregator(feed): isQuotaWindow accepts any string as resetsAt and any finite used/limit/percent — an impossible reset date is clocked as Mar 2 in guidance, a -50% window reads healthy and a 15000% window walls a pool #3427/aggregator(feed): isBurnSegment accepts negative tokens, non-date from/to and inverted ranges — garbage burn rows survive sanitizeQuotaView and render as measured history #3428/aggregator(feed): isQuotaPool never checks credential-row label/freshness or activeSessions — a windows-only credential row or a null session crashes renderQuota #3921 quota tests still pass.
Related
- aggregator(feed): isQuotaPool never checks credential-row label/freshness or activeSessions — a windows-only credential row or a null session crashes renderQuota #3921 — parent finding (credential-row/session shape sanitization, implemented by PR fix(aggregator): sanitize quota credential/session rows (#3921) #4508); this issue is the pool-level/value residual its criteria did not cover.
- aggregator(feed): isQuotaWindow accepts any string as resetsAt and any finite used/limit/percent — an impossible reset date is clocked as Mar 2 in guidance, a -50% window reads healthy and a 15000% window walls a pool #3427 / aggregator(feed): isBurnSegment accepts negative tokens, non-date from/to and inverted ranges — garbage burn rows survive sanitizeQuotaView and render as measured history #3428 — the value-rule precedents for quota windows and burn segments in the same file.
Activity
dezren39 commentedon Nov 2, 2026
🤖 Agent note · filed
new-issue-creator-code-a)new-issue-creator-code-a, run 2026-11-02 13:05 CSTmeasuredAtnot date-checked, negativeburnTokensPerMinkept.sanitizeQuotaViewdropping/validating those fields with drop counts surfaced, plus regression tests for probe cases P1–P5 infeed.test.ts.~/git/fleet/probe-2026-11-02-laneA-quotapool/(laptop, mainc84bbcfa1, feed.ts md50d344ffcc96d83587ae2aa511da23c1e); parent aggregator(feed): isQuotaPool never checks credential-row label/freshness or activeSessions — a windows-only credential row or a null session crashes renderQuota #3921 / PR fix(aggregator): sanitize quota credential/session rows (#3921) #4508dezren39 commentedon Nov 2, 2026
🤖 Agent note · picked up
repo-worker-code, lane02cafe76-eafd-4d0b-aaa6-2b7a737d68dc)ses_e5e62396816ffe73OM9YgZ577v; queue task64479 remaining items
dezren39 commentedon Nov 2, 2026
🤖 Agent note · handed off
opencodeby repo-queue.py lane, so this lane hands off per runbook §1b and leaves task 6451 CLAIMED for the opencode claimant poll.dezren39 commentedon Nov 2, 2026
🤖 Agent note · handed off (claimant launch)
dezren39 commentedon Nov 3, 2026
agent-note:v1
event: picked_up
task: 7415 (repo-health-code-pilot; worker repo-worker-code; OpenChamber scheduled lane c29174f1-48e0-4b13-b4ff-9b73ab67e9ab)
state: claimed (attempt 1). Triage: checking for in-flight work first per packet, then verifying at current main.
dezren39 commentedon Nov 3, 2026
agent-note:v1
event: triaged_done
task: 7415 (repo-health-code-pilot; worker repo-worker-code; OpenChamber scheduled lane c29174f1-48e0-4b13-b4ff-9b73ab67e9ab)
state: fix already landed — closing with evidence.
evidence (all at true remote main ce2f197, worktree ~/git/fleet/6992-2212-phase3):
action: ticking all five acceptance boxes and closing. Labels cleaned (in-flight queue/status/work removed). No new PR needed.
bookkeeping: sandbox backlog and sweep log deferred to fleet reconciliation.