Skip to content

meta-exporter: window_duration_secs is never validated — a missing/junk duration exports a 'window-NaNs' window as a successful reading #1566

Closed

Description

@dezren39

Bug

pm-stack/meta-exporter/meta-quota-export.mjs — parseSubscriptionQuota never validates window_duration_secs, even though the module's contract is fail-closed: "Parse a subscription-quota payload into export windows. Throws on any shape drift — fail-closed, never partial zeros." (meta-quota-export.mjs:67-68)

The parser carefully validates window_weighted_used/limit, weekly_weighted_used/limit, and both *_resets_at fields for finiteness and non-negativity (:76-87), and rejects zero limits (:88-90) — but durationSecs is read at :79 and used unchecked at :91 to name the short window:

const shortName = durationSecs === 18_000 ? "5h" : durationSecs === 3_600 ? "1h" : `window-${durationSecs}s`;

Verified this run (node, against the real module on main db6f7d0)

With an otherwise-valid payload (the captured fixture shape from meta-quota-export.test.mjs):

window_duration_secs Result
missing OK — windows ["window-NaNs", "weekly"]
"abc" OK — windows ["window-NaNs", "weekly"]
-5 OK — windows ["window--5s", "weekly"]
0 OK — windows ["window-0s", "weekly"]

So a single drifted field in the console API response produces a success document (status: "ok") carrying a garbage-named window with a real used-percent — exactly the "partial/fake reading" outcome the fail-closed design exists to prevent.

Why it matters

The aggregator's file-export mapper passes window names through verbatim and only knows durations for the names "5h" and "weekly" (pm-stack/aggregator/src/quota-gather-map.ts: FILE_EXPORT_WINDOW_SECONDS = { "5h": 18_000, weekly: 604_800 }, and the window loop at :144-155 pushes any named window with windowSeconds: FILE_EXPORT_WINDOW_SECONDS[w.name] ?? null). A window-NaNs window therefore lands in quota-current as a live "ok" window with a nonsense name and no duration, instead of the export failing closed with an unparseable failure document that consumers can alert on. Pool/quota consumers keying on the 5h window silently lose the real short window while the service still reports healthy.

Parent feature: #1301 (Meta adapter Phase 1 — this exporter).

Acceptance criteria

  • parseSubscriptionQuota validates window_duration_secs like the other numeric fields: it must be a finite number > 0; a missing, non-numeric, zero, or negative value throws ExportError("unparseable", 6, …) naming the field.
  • Well-formed payloads are unchanged: 18000 → 5h, 3600 → 1h, any other positive duration → window-<n>s (the forward-compatible naming for a genuinely new window length stays).
  • Tests in meta-quota-export.test.mjs add the missing / "abc" / 0 / negative window_duration_secs cases to the existing "shape drift fails closed" test family, asserting they throw.
  • No change to the success/failure document shapes or exit codes.

Activity

  1. developing-today commented on Oct 28, 2026

    @developing-today
    Contributor
  2. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    priority/normalOrdinary priority (the default)
    app/pm-stackpm-stack (Pad/Grist) in developing-today/code
    effort/sSmall: expected under 2 hours of work
    on Oct 28, 2026
  3. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

    • Agent: new-issue-creator-code-b (Lane B, developing-today/code)
    • Session / ID: cron job new-issue-creator-code-b, run 2026-10-27 21:20 CDT
    • Found via: filed this run
    • Task: Filed after verifying on main db6f7d0 with node against the real module: parseSubscriptionQuota in pm-stack/meta-exporter/meta-quota-export.mjs validates every numeric quota field except window_duration_secs (:79 read, :91 used unchecked). Missing duration → windows ["window-NaNs","weekly"], "abc" → "window-NaNs", -5 → "window--5s", 0 → "window-0s" — all returned as a successful parse, contradicting the module's fail-closed contract (:67-68). The aggregator's file-export mapper (quota-gather-map.ts FILE_EXPORT_WINDOW_SECONDS + :144-155) passes unknown window names through with windowSeconds null, so the bogus window reaches quota-current as a live ok window. Enqueued as a triage packet to repo-health-code-pilot.
    • Expectation: triage (effort s) confirms and routes the fix: validate window_duration_secs finite > 0 (unparseable/6 otherwise), positive-duration naming unchanged, drift cases added to meta-quota-export.test.mjs.
    • Links: packet hidden_files/packet-1566.json · body hidden_files/issue-code-meta-exporter-duration-body.md
  4. added
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 28, 2026
  5. 26 remaining items

  6. added
    status/parkedDeliberately paused with a recorded resume condition
    queue/claimedQueue worker lifecycle state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Oct 28, 2026
  7. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

    • Agent: queue worker (repo-worker-code), lane A shift
    • Session / ID: queue task 1833 (resumed claim, 2026-10-28T14:43Z)
    • Found via: queue claim
    • Task: Implement the verified triage brief: validate window_duration_secs fail-closed in pm-stack/meta-exporter/meta-quota-export.mjs (parseSubscriptionQuota) + drift cases in its test file. Laptop SSH is back, so the earlier park reason no longer applies.
    • Expectation: effort/s — done = PR opened (and merged if CI green) with missing/'abc'/0/negative durations throwing ExportError('unparseable', 6) naming the field; valid naming (18000→5h, 3600→1h) unchanged.
    • Links: branch queue/1833-1566-window-duration-validation (to create on laptop)
  8. added a commit that references this issue on Oct 28, 2026
  9. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

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/sSmall: expected under 2 hours of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/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