Repository navigation
Description
pm-stack(aggregator): applyCloudflareExport accepts negative used values — the Supabase overlay refuses them
Evidence
pm-stack/aggregator/src/saas-extract.ts, applyCloudflareExport (line ~831): the export-metric filter accepts any finite used:
.filter((m) => m && typeof m.id === "string" && typeof m.used === "number" && Number.isFinite(m.used))The sibling overlay in the same file, applySupabaseExport (lines ~941-947), explicitly drops negative measurements:
!(typeof m.used === "number" && m.used < 0) &&
!(typeof m.limit === "number" && m.limit < 0),and the Supabase billing gate in the same function also requires billedUsd >= 0 (line ~982). The Cloudflare path has no equivalent guard, so a negative used from the file-export document is copied onto the card and its percent is derived from it (line ~843: percent: ... Math.round((live.used / m.limit) * 1000) / 10), and the card is stamped sourceClass = "api" — presented as live measured data.
Verified this run (laptop bun probe at origin/main 115fe4f)
Fresh, in-cycle Cloudflare export doc with workers-requests: used = -500 (control kv-reads: used = 1420):
workers-requests used= -500 percent= -0
kv-reads used= 1420 percent= 0
sourceClass= api
The negative measurement is stored on the service card. With a larger magnitude (e.g. used = -5,000,000 against the 10M limit) the derived percent is -50 — a negative usage percentage rendered as measured fact.
Why it matters
The export document is produced by an external collector writing a file; a buggy or drifted collector value flows straight through this overlay onto the usage card as authoritative "live" data. The Supabase overlay in the same file already encodes the house rule — negative usage/limit measurements are not measurements and are dropped, keeping the tracker prose fallback. The Cloudflare overlay is the inconsistent half of the pair.
Acceptance criteria
applyCloudflareExportdrops export metrics withused < 0(mirroringapplySupabaseExport's filter), so the affected metric keeps its prose/null state instead of a negative measured value.- A regression test in
pm-stack/aggregator/test/cloudflare-export.test.ts: a fresh doc carrying a negativeusedleaves that metric unchanged (and does not set a negative percent), while other valid metrics in the same doc still overlay. - Existing cloudflare-export and saas test suites pass.
Activity
dezren39 commentedon Nov 3, 2026
🤖 Agent note · state: filed
usedfrom the Cloudflare export doc and stores it on the card with a derived negative percent, while sibling applySupabaseExport in the same file explicitly drops negative used/limit metrics. Verified by laptop bun probe at origin/main 115fe4f: used=-500 stored, percent=-0, card stamped sourceClass=api.dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed off
dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed off
ses_e5e5e14fb8bffeiIS7fJHjbq5Qrepo-worker-code(bound worker uses this id for all queue helper verbs)opencode-route/workhorse, agentbuild6 remaining items
dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed off
dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed off
dezren39 commentedon Nov 4, 2026
🤖 Agent note · handed off
opencode; handed off to the laptop claimant (opencode-claimant), which launches the bound opencode session to drive task 8048 to its terminal state.Merge pull request #4976 from developing-today/queue/8048-4942-cf-neg…
dezren39 commentedon Nov 4, 2026
🤖 Agent note · picked up
dezren39 commentedon Nov 4, 2026
🤖 Agent note · done
already_done.ef55926de2c3481591ad69c6a576bd504a792204.