Skip to content

feat(usage-hub): v2 Cloudflare live collector — hourly analytics feed + billing scope #1048

Closed

Description

@dezren39

Part of epic #1047. Hub design §2.2 / §5 v2.

Build the Cloudflare live collector for the Usage & billing hub:

  • Hourly rollup into the fleet feed's saas section (GraphQL analytics + product APIs with the day-to-day token): Workers requests + CPU-ms vs 10M/30M, KV reads/writes, D1 rows read/written, Queues ops, R2 storage + Class A/B ops, Workers AI neurons/day.
  • Today almost every Cloudflare metric on /quota renders used: null ("current-cycle usage not read"). Acceptance: live API values with measured-at + source on the card and detail page; snapshot records appended per §4.
  • Billing gap: the subscriptions/billing endpoint returned 403 with the day-to-day token. Resolve the scope (new scoped token in Bitwarden if needed) or formally settle for invoice-only billing state (monthly invoice, next Nov 2) and document which in quota-view Part (b).
  • Billed vs not-yet-billed must both show, per goal_4bd599c9ab26.

Activity

  1. developing-today commented on Oct 27, 2026

    @developing-today
    Contributor
  2. dezren39 commented on Oct 27, 2026

    @dezren39
    MemberAuthor

    Sub-tasks named in the 2026-10-26 v2/v3 design pass (hub-v2-v3-design-2026-10-26.md §2):

    • R2 bucket inventory refresh: quota-view Part (b) records R2 storage ~2 GB from the tracker inventory with the note "bucket inventory needs refresh" — the collector should enumerate buckets/objects directly rather than inherit that figure.
    • Long-tail detail metrics for /quota/service/cloudflare: the original goal's example set (1/1 free WAFs in use, 50/10,000 rules enabled class metrics) belongs on the detail page; capture which of these the API can actually return and mark the rest console-only.
  3. dezren39 commented on Oct 27, 2026

    @dezren39
    MemberAuthor

    Cadence change (2026-10-26, Stage-2 quota-plane design, epic #1149): Cloudflare collection moves from this issue's hourly rollup to the quota-gatherer's 15-minute tick (#1151). This issue's scope (GraphQL analytics coverage + the billing-scope 403 resolution) is unchanged — deliver it as the gatherer's Cloudflare adapter rather than a standalone hourly job.

  4. added
    work/assignedAn agent holds this item via the queue (claimed task)
    queue/claimedA queue worker has claimed the task for this item
    on Oct 29, 2026
  5. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  6. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

    Verdict: CONFIRMED — no live Cloudflare collector exists at HEAD a3cdf6c9a35df1ff8b88b7a02d62e5c04ca4c94a; the /quota Cloudflare card still renders used: null from hand-written tracker prose.

    Evidence (fresh reads of current main, not the issue text):

    • pm-stack/aggregator/src/saas-extract.ts, cloudflareMetrics: Workers requests (and KV, D1, Queues, R2 ops…) are pushed with limits parsed from tracker prose and no used value (metric() defaults it to null), carrying the note verbatim: "Current-cycle usage not read — billing/analytics scope is not established for the day-to-day token." R2 storage's note: "Footprint read from the Tracker inventory; bucket inventory needs refresh." — both sub-tasks from the 2026-10-27 comment are still owed.
    • pm-stack/aggregator/scripts/gather-quota.ts — the landed feat(quota-plane): quota-gatherer service in the PM stack — 15-minute tick, quota-current contract #1151 quota-gatherer this issue was re-routed onto (2026-10-27 cadence comment) — has exactly two input families (the OpenChamber quota module and Meta-style file exports) and no Cloudflare adapter; quota-gather-map.ts / quota-current.ts / quota-extract.ts have none either. feat(quota-plane): quota-gatherer service in the PM stack — 15-minute tick, quota-current contract #1151 closed without delivering this issue's scope.

    Routing: follow-up enqueued as queue task 2983 (small_fix, dedupe repo-health:v1:fix:developing-today/code:issue:1048, packet queue-packets/packet-1048-fix.json), shaped per the cadence amendment — a pm-stack/cloudflare-export/ producer mirroring meta-exporter's fail-closed file-export convention on the gatherer's 15-minute tick (GraphQL analytics + product APIs with the day-to-day token, referenced by Bitwarden name only; direct R2 bucket/object enumeration), minimal aggregator wiring to prefer a fresh export for the card's used values, and the billing path pinned to the issue's own fallback: probe subscriptions/billing, and on the known 403 document invoice-only in quota-view Part (b). Creating a new Cloudflare token is explicitly out of the packet's scope — that is an account action for Drew, and the packet instructs the worker to record the exact missing scopes on this issue instead if analytics also 403s. This issue stays open and is labelled queue/queued for that task.

  7. added
    queue/queuedHas a queued task in the Supabase agent queue
    work/assignedAn agent holds this item via the queue (claimed task)
    and removed
    queue/claimedA queue worker has claimed the task for this item
    work/assignedAn agent holds this item via the queue (claimed task)
    on Oct 29, 2026
  8. 68 remaining items

  9. added
    status/parkedDeliberately paused with a recorded resume condition
    on Oct 29, 2026
  10. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · parked

  11. added
    queue/claimedA queue worker has claimed the task for this item
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Oct 29, 2026
  12. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  13. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · escalated

  14. added
    queue/blockedQueue task is blocked (reason recorded on the task)
    status/blockedBlocked on something named in the issue/PR
    user/escalatedMuse reviewed it; the decision is genuinely the user's — escalated with Muse's read attached
    and removed
    queue/claimedA queue worker has claimed the task for this item
    on Oct 29, 2026
  15. added a commit that references this issue on Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

meta/follow-upFollow-up spun out of earlier workqueue/blockedQueue task is blocked (reason recorded on the task)status/blockedBlocked on something named in the issue/PRuser/escalatedMuse reviewed it; the decision is genuinely the user's — escalated with Muse's read attachedwork/assignedAn agent holds this item via the queue (claimed task)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions