Repository navigation
Description
Summary
In the aggregator's quota-current overlay, the stale-path "newest entry" pick is not
finite-gated, so a garbage or far-future measuredAt wins it — the pool's displayed
freshness (stamp + source) then comes from the bad write instead of the newest real read.
Evidence (main 24901e7, pm-stack/aggregator/src/quota-current.ts)
parseQuotaCurrent(:57) accepts any stringmeasuredAt— no parseability check.entryState(:65-72) is correctly finite-gated (the aggregator: a future-dated gatherer read is 'fresh' forever until its date passes — quota-current freshness has no upper bound, so one skewed measuredAt pins a pool's windows for weeks #1541 fix): an unparseable or60s-future stamp classifies
stale, neverok.- But when no fresh-ok entry exists,
overlayQuotaCurrentpicks the entry to represent
the pool with a raw sort (:169):
[...entries].sort((a, b) => Date.parse(b.measuredAt) - Date.parse(a.measuredAt))[0]
and passes it toapplyEntry, which stampspool.freshness = { measuredAt: entry.measuredAt, source: entry.source, state }(:99-106).
Verified this run with a Bun probe calling the real overlayQuotaCurrent /
parseQuotaCurrent (fixtures mirrored from test/quota-current.test.ts), now =
2026-10-27T07:00:00Z, service meta:high-usage:
parseQuotaCurrentACCEPTS an entry withmeasuredAt: "not-a-date".- Garbage entry listed first + a real 2h-old read second → pool freshness =
{"measuredAt":"not-a-date","source":"garbage-src","state":"stale"}— the NaN
comparator (Date.parsediff) is treated as 0, so the winner is file-order dependent
and the garbage stamp shadows the real read. Reversed order picks the real read. - A +30d future entry vs a real 1h-old read → freshness =
{"measuredAt":"2026-11-26T07:00:00.000Z","source":"future-src","state":"stale"}—
the skewed write outranks the newest real stale read for as long as the skew lasts. - Control (two real stale reads) correctly picks the newer one.
Why it matters
The module's own stated intent (#1541, comment at :37-44) is that one skewed write
cannot pin a pool or outrank genuine reads. That holds for the fresh path, but the
stale path still lets a skewed/garbage write become the pool's displayed freshness:
the dashboard shows an unparseable or weeks-future stamp and the wrong source, and
downstream age rendering (Date.parse on the stamp) produces NaN ages. The winner
also depends on provider order in the file when a stamp is unparseable.
Acceptance criteria
- The stale-path newest pick ignores entries whose
measuredAtdoes not parse to a
finite time (orparseQuotaCurrentrejects them), so the newest parseable stale
read represents the pool. - A future-dated entry beyond
QUOTA_CURRENT_FUTURE_SKEW_MSdoes not outrank a
parseable past read in the stale-path pick. - Regression tests in
test/quota-current.test.ts: garbage-first vs garbage-second
orderings give the same result; future-vs-stale picks the real stale read. - Existing quota-current tests still pass.
Related: #1541 (closed — fresh-path skew gate; this is the stale-path residual),
#2242 (same stamp-validation pattern in health.ts, different module).
Activity
developing-today commentedon Oct 29, 2026
CODE-1117
dezren39 commentedon Oct 29, 2026
agent-note:v1
state: filed
agent: new-issue-creator-code-b
Found via: filed this run — read quota-current.ts end-to-end after the sibling extractors were mined out; verified with a sandbox Bun probe driving the real overlayQuotaCurrent/parseQuotaCurrent (fixtures mirrored from test/quota-current.test.ts, main 24901e7): garbage measuredAt accepted by parseQuotaCurrent and wins the stale-path newest pick when first in file order (freshness stamped "not-a-date"); a +30d future stamp outranks a real 1h-old stale read. NOT self-solved: whether the gate lives in parseQuotaCurrent or the overlay sort is triage's pin. Dedup: #1541 (closed) gated only the fresh path; #2242 is health.ts, distinct module.
15 remaining items
dezren39 commentedon Oct 31, 2026
🤖 Agent note · picked up
dezren39 commentedon Oct 31, 2026
🤖 Agent note · parked
fix(aggregator): finite-gate the quota-current newest pick (#2253) (#…
dezren39 commentedon Oct 31, 2026
agent-note:v1 — task 4315 completed by lane F: PR #3084 MERGED (squash 69b2397), this issue auto-closed. Semantics reconciliation (the reason for the earlier park): the park note claimed the packet requires finite future timestamps to retain time ordering; lane F re-read the authoritative sources — the triage pin from task 3408 on this issue (non-finite = -Infinity at all five sort sites, parse stays lenient; silent on beyond-skew) and this issue's own summary/probe (a far-future measuredAt winning the stale-path pick IS the bug; +30d future vs real 1h-old stale read must resolve to the real read). PR 3084 satisfies both: non-finite and beyond-skew (QUOTA_CURRENT_FUTURE_SKEW_MS, the same bound entryState uses) sort as -Infinity; finite stamps within skew keep time ordering; parseQuotaCurrent untouched. Codex review clean on 7ba170e; lane F independently re-ran bun test test/quota-current.test.ts on the laptop: 28/28 pass.