Skip to content

aggregator: summarizeDns ages renewals by the UTC day, not Chicago — a domain renewing today vanishes from Next renewal and the 45-day spend card every evening from 19:00 CDT #1684

Closed

Description

@dezren39

Summary

summarizeDns (pm-stack/aggregator/src/dns.ts:99-102) derives "today" and the 45-day spend-horizon cutoff from Date#toISOString() — the UTC calendar day:

const cutoff = new Date(now.getTime() + soonDays * 86_400_000).toISOString().slice(0, 10);
const today = now.toISOString().slice(0, 10);

The dashboard's house convention is America/Chicago: derive.ts:457-475 already provides chicagoYmd(now) ("2026-10-25" in America/Chicago for an instant) and addDaysYmd(ymd, n) for exactly this kind of date-only comparison — the helpers the #1629 fix introduced for freshness(). dns.ts uses neither.

Verified behaviour (probe run on the laptop, main d39e611)

Probe test in the real aggregator tree (bun test, detached worktree; dns.ts sha256 10933bba identical in both clones), with a register holding domains renewing 2026-10-27 and 2026-10-28:

  • CTRL — now = 2026-10-27T15:00:00Z (10:00 CDT; UTC and Chicago agree on the date): nextRenewal = the 2026-10-27 domain, renewingSoon = both domains. ✅
  • BUG — now = 2026-10-28T01:30:00Z (2026-10-27 20:30 CDT — still Oct 27 for the viewer): nextRenewal returns the 2026-10-28 domain and renewingSoon drops the 2026-10-27 domain entirely. The domain renewing today (Chicago) vanishes from both the "Next renewal" card and the "Renewing in 45 days" spend card (render.ts:2533-2545) every evening from 19:00 CDT until midnight — and symmetrically, tomorrow's renewal is presented as today's for those five hours.

The existing dns tests (test/slice3.test.ts, 19 pass on the same tree) exercise summarizeDns only at 2026-12-28T00:00:00Z — midnight UTC, where UTC and Chicago dates differ too (Dec 27 18:00 CST) but the fixture's renewal dates are far enough away that the one-day shift changes nothing.

Why it matters

The /dns page is the fleet's renewal-spend surface: "Next renewal" and "Renewing in 45 days · $total" are how upcoming domain spend is spotted. For five hours every evening the page skips the domain that renews that day and understates the 45-day total by that domain's price — a wrong answer on a money page, in the timezone the rest of the aggregator already standardised on.

Acceptance criteria

  • summarizeDns computes today via the Chicago calendar (reuse chicagoYmd from derive.ts) and the cutoff via addDaysYmd(today, soonDays) or an equivalent Chicago-anchored computation — no toISOString().slice(0, 10) day derivation left in dns.ts.
  • Regression test: at 2026-10-28T01:30:00Z (Oct 27 evening CDT) a domain renewing 2026-10-27 is nextRenewal and appears in renewingSoon; a domain renewing 2026-10-28 also appears in renewingSoon.
  • The existing slice3 dns tests keep passing, including the midnight-UTC summary case.
  • A DST-boundary case is pinned (e.g. an instant during the CDT→CST transition week) so the cutoff arithmetic cannot drift by an hour into the wrong day.

Scope notes

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/aggregatorPackage/app: aggregator (pm-stack in this repo)
    effort/sSmall: expected under 2 hours of work
    on Oct 28, 2026
  3. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

  4. 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 31, 2026
  5. 13 remaining items

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

    @dezren39
    MemberAuthor

    agent-note:v1 | worker repo-worker-code (Lane D, task 4242) | parked — CI + Codex pending on PR #3060

  8. added
    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 31, 2026
  9. dezren39 commented on Oct 31, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  10. dezren39 commented on Oct 31, 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/aggregatorPackage/app: aggregator (pm-stack in this repo)effort/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 jobtask/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