Repository navigation
Description
Problem
entryFromTurso (pm-stack/aggregator/src/quota-gather-map.ts:405) never range-checks the Turso usage counts it maps. Its only numeric gate is the shared helper at quota-gather-map.ts:38:
const num = (v: unknown): number | null => (typeof v === "number" && Number.isFinite(v) ? v : null);Finite is the whole check — a negative count passes. The five usage fields are read through it (databases :453, storage_bytes :455, rows_read :463, rows_written, bytes_synced :479), converted with gb() (:390) / pct3() (:391), and pushed as windows on an entry whose state becomes "ok" (no error) as long as at least one window exists. The gatherer caller passes the raw API JSON straight in with no intervening validation (pm-stack/aggregator/scripts/gather-quota.ts:301, entryFromTurso(usage, subscription, { measuredAt: tickIso })).
Verified this run (laptop probe, real module, main 02c774a)
Probe: laptop ~/git/fleet/probe-2026-10-29-laneA-tursoneg/probe.ts (Bun, imports the real quota-gather-map.ts; the laptop copy is md5-identical to sandbox main).
Feeding usage = { databases: -3, storage_bytes: -2_000_000_000, rows_read: -1000, rows_written: -5, bytes_synced: -1_000_000_000 } with a normal Starter subscription doc:
- Entry state is
ok, errornull. - Windows publish impossible values:
databases value -3, pct -3, label "-3 / 100";storage value -2, pct -40, label "-2 GB / 5 GB";sync value -1, pct -33.333; rows windows carry negative raw values (their pct rounds to-0). recordsFromEntries([entry], …)then appends negative snapshot records for the native-unit series:{metricId: "databases", value: -3, unit: "count"},{metricId: "storage", value: -2, unit: "gb"},{metricId: "sync", value: -1, unit: "gb"}— so one bad read does not just render badly, it writes impossible points into the pool's snapshot history.- A mixed read (
databases: 3, rows_read: -42) is alsook, with the negative metric published alongside the good one — there is no per-metric rejection either.
Control: a normal read (databases: 3) maps to ok with only that window, as the existing tests expect.
Why it matters
Usage counts (databases, bytes stored/synced, rows read/written) cannot be negative. A Turso API shape drift, a partial/incorrect response, or a future endpoint change that returns a signed delta instead of a total would currently be stamped as fresh live measured data, shown on the Turso SaaS card as negative usage / negative percent-of-limit, and persisted as negative snapshot points that later pace/chart/history code has to interpret. Every sibling mapper in this stack that was audited for the same class treats negative amounts as invalid (cf. #2508 saas-extract, #2493 github-billing, #2492 supabase-export) — the Turso mapper is the one that was missed. Whether one negative metric should poison the whole entry (fail-closed error entry, the file-export adapter discipline) or just that metric (omit, like missing metrics) is the triage decision this issue asks for — silently publishing it is the one outcome that is wrong either way.
Acceptance criteria
- A Turso usage doc carrying a negative value for any of
databases,storage_bytes,rows_read,rows_written, orbytes_syncedno longer produces anokentry with a negative window: either the affected metric is omitted or the entry is an error entry (triage pins which, consistent with this module's fail-soft conventions), and the chosen behaviour is documented at the mapper. -
recordsFromEntrieson such an entry appends no negative-value snapshot record. - Regression tests in pm-stack/aggregator/test/quota-gather-map.test.ts cover at least: an all-negative usage doc, and a mixed doc with one negative metric among valid ones.
- Existing behaviour is unchanged for valid, missing (omitted, never zeroed), and non-numeric metrics, and the existing
entryFromTursotests still pass.
Dedup notes
Searched open + closed for entryFromTurso, "turso negative", and quota-gather-map: #2332 is this file's entryFromResult fetchedAt RangeError (a different function and failure), #2416 is parseQuotaCurrent window entries, #1049 is the original Turso collector feature. The negative-amount issues #2492/#2493/#2508 cover the supabase-export, github-billing, and saas-extract mappers respectively — none touches entryFromTurso.
Activity
dezren39 commentedon Oct 30, 2026
🤖 Agent note · filed
51 remaining items
dezren39 commentedon Nov 2, 2026
🤖 Agent note · parked
7d0abb7e1a4be18b1e6dd00bd56799a17e9c362e. Drew-owned PR hard stop; no PR internals inspected.dezren39 commentedon Nov 2, 2026
🤖 Agent note · parked
dezren39 commentedon Nov 2, 2026
🤖 Agent note · picked up — OpenChamber scheduled lane
awaiting_cicheckpointdezren39) at7d0abb7e1a4be18b1e6dd00bd56799a17e9c362e.dezren39 commentedon Nov 2, 2026
🤖 Agent note · parked — OpenChamber scheduled lane
7d0abb7e1a4be18b1e6dd00bd56799a17e9c362e. Drew-owned PR is a hard stop. No PR internals or worktree/source were inspected.queue/parked,status/parked, andwork/assignedremain synchronized.dezren39 commentedon Nov 2, 2026
Task 5364 resumed by lane A. Prior park premise corrected: PR #4207 is fleet-owned (branch queue/5364-2553-turso-negative-guard, PR body names task 5364) — author metadata alone is not Drew-ownership. Fresh verification at head 7d0abb7: Codex review completed, no findings; laptop bun test test/quota-gather-map.test.ts 35/35 pass. Merging PR #4207 under standing merge authority (CI test check still QUEUED in the known runner backlog).
fix(aggregator): entryFromTurso omits negative usage metrics (#2553) (#…
dezren39 commentedon Nov 2, 2026
Task 5364 done: PR #4207 squash-merged (082f5ba), #2553 closed. Fresh laptop verification at head 7d0abb7: bun test test/quota-gather-map.test.ts 35/35 pass; Codex review completed with no findings. CI test check was still QUEUED at merge time (known runner backlog); merged under standing merge authority on laptop-verified tests.