CopilotKit / CopilotKit/outpost
Onboarding digest: DST boundary yields a zero-width date window (reports 0 members)
Nobody has claimed this yet.
- 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 inafterEach, so a failed assertion leaks a stubbed globalfetchand a silenced
console.loginto every later test. - The console-fallback test leaves
fetchunstubbed 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 withvi.setSystemTime. vi.clearAllMocks()keeps implementations, so a persistentmockResolvedValue([])leaks and
would silently satisfy an unexpected thirdfindManycall.computeFunnelMetricsarguments are never asserted, so swapping the two query results stays
green.- The
DISCORD_TOKEN-missing-while-channel-set branch (handler throws) is untested. mock.callsis annotatednumber[]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
pinsTZ=Europe/Berlinon 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.setSystemTimewhere "today" is under test
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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