Skip to content

meta-exporter: parsePaygBalance silently truncates any balance whose decimals aren't exactly two — '$1,234.5' exports 1234 and '$1,234.567' exports 1234.56 #2461

Closed

Description

@dezren39

meta-exporter: parsePaygBalance silently truncates any balance whose decimals aren't exactly two — "$1,234.5" exports 1234 and "$1,234.567" exports 1234.56

Evidence (verified this run, main 5a34fa70)

pm-stack/meta-exporter/meta-quota-export.mjs, parsePaygBalance (lines 113–119):

const m = iframeText.match(/Current balance\s*\n?\s*\$\s*([\d,]+(?:\.\d{2})?)/);

The capture is not anchored at the end of the amount: the regex matches a prefix of a longer number and returns it as the balance.

Probe (node, importing the real module from main):

iframe text exported paygBalanceUsd
Current balance\n$1,234.56 1234.56 ✅ (existing test case)
Current balance\n$1,234.5 1234 — the .5 is silently dropped
Current balance\n$1,234.567 1234.56 — the third decimal is silently dropped

Why it matters

The function's own documented contract is that a balance it cannot read stays null — "an absent read must stay absent, never become a fake $0." A truncated balance is a fake value of exactly the same kind: if the billing page's format drifts (one decimal shown, a trailing digit group, a different rounding), the exporter publishes a wrong — always lower — PAYG balance as a measured fact in a status: "ok" document, and the quota gatherer (#1151) ingests it. Returning null on anything that isn't a clean, fully-consumed amount preserves the fail-closed design; silently truncating does not.

Acceptance criteria

  • parsePaygBalance returns the exact value only when the amount is consumed completely; a digit or decimal point immediately following the matched amount makes the read null (amount-ending boundary pinned by triage — e.g. a negative lookahead or an explicit end anchor that still tolerates the text that follows the balance on the real page).
  • New tests in meta-quota-export.test.mjs: "$1,234.5" → null; "$1,234.567" → null; the existing cases ($0.00 → 0, $1,234.56 → 1234.56, no-match → null, non-string → null) still pass (node --test pm-stack/meta-exporter/).

Dedup

#2175 (CDP timeouts), #2350 (entry-point check), #1566 (closed, window_duration_secs) are distinct mechanisms. Sibling filed this run: #2460 (subscription-quota epoch range validation — different function, different mechanism).

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    task/triageQueue packet kind: verify, reproduce, and route this item
    source/creatorFiled by the new-issue-creator job
    priority/lowNice to have; do when convenient
    on Oct 29, 2026
  2. developing-today commented on Oct 29, 2026

    @developing-today
    Contributor
  3. added
    queue/queuedHas a queued task in the Supabase agent queue
    effort/xsTrivial: expected under 30 minutes of work
    app/pm-stackpm-stack (Pad/Grist) in developing-today/code
    on Oct 29, 2026
  4. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

  5. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 30, 2026
  6. 19 remaining items

  7. added
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 1, 2026
  8. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  9. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · PR opened

    • Agent: queue worker (repo-worker-code), OpenChamber scheduled lane
    • Session / ID: queue task 5605
    • Branch: queue/5605-2461-reject-truncated-payg · commit 6313cd8
    • PR: fix(meta-exporter): reject truncated PAYG balances (#2461) #3697
    • Change: the amount regex now blocks following digits, commas, and decimal points, preventing silent truncation and comma-backtracking; tests cover malformed decimals, valid integers/amounts, and trailing page text.
    • Validation: node --test pm-stack/meta-exporter/*.test.mjs — 18/18 pass; git diff --check passes.
    • Next: checking CI and review state; will merge if all gates pass or park if CI is pending.
  10. added a commit that references this issue on Nov 1, 2026
  11. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done (already merged)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/pm-stackpm-stack (Pad/Grist) in developing-today/codeeffort/xsTrivial: expected under 30 minutes of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/lowNice to have; do when convenientsource/creatorFiled by the new-issue-creator jobstatus:donetask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions