CopilotKit / CopilotKit/outpost

Onboarding digest: DST boundary yields a zero-width date window (reports 0 members)

Open
#140 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area: infrastructure roadmap roadmap: next
Dominant language
TypeScript
Stars
7
Forks
3
Avg merge
7d 16h
Merged PRs (30d)
15

Description

Summary

ONBOARDING_DIGEST computes its date window by mixing UTC normalization with local
getDate/setDate. On a DST boundary the window collapses to zero width (since === until)
and the digest reports 0 new members while appearing to succeed.

Found during a code review of an unrelated PR. The bug shipped in #133, and the tests added
there did not catch it because they only assert instanceof Date on the boundaries, never
their values.

Reproduction

packages/outpost/queue/src/handlers/onboarding-digest.ts — window computation. Under
TZ=Europe/Berlin on 2026-03-29 (spring-forward), since and until come out equal, so the
joinedAt: { gte, lt } query matches nothing.

Test-hygiene items in the same file

packages/outpost/queue/src/__tests__/onboarding-digest.test.ts:

  • Cleanup (vi.unstubAllGlobals(), mockRestore()) sits at the end of test bodies rather
    than in afterEach, so a failed assertion leaks a stubbed global fetch and a silenced
    console.log into every later test.
  • The console-fallback test leaves fetch unstubbed entirely, so a regression in that branch
    would issue a real network call instead of failing.
  • The date-range test asserts only instanceof Date — this is precisely the gap that let the
    DST bug through.
  • The current-date default is compared against a freshly recomputed new Date(), so it flakes
    across UTC midnight; freeze with vi.setSystemTime.
  • vi.clearAllMocks() keeps implementations, so a persistent mockResolvedValue([]) leaks and
    would silently satisfy an unexpected third findMany call.
  • computeFunnelMetrics arguments are never asserted, so swapping the two query results stays
    green.
  • The DISCORD_TOKEN-missing-while-channel-set branch (handler throws) is untested.
  • mock.calls is annotated number[] instead of the [number] tuple, defeating
    signature-change detection.

Acceptance criteria

  • Window computation is timezone-consistent (all UTC or an explicit tz), with a test that
    pins TZ=Europe/Berlin on 2026-03-29 and fails against the current implementation
  • The date-range test asserts the actual boundary values, not just their type
  • Stub cleanup moves to afterEach
  • No test can issue a real network call
  • Clock frozen via vi.setSystemTime where "today" is under test

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/outpost/queue/src/handlers/onboarding-digest.ts and packages/outpost/queue/src/tests/onboarding-digest.test.ts. Read the existing window and test setup, then run the onboarding-digest tests while checking the listed DST, cleanup, network, clock, mock, argument, error-branch, and tuple cases. Done means every acceptance criterion is covered without real network calls or leaking test state.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend, testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.