Description
while reading through the daily streak processor i noticed the daysDiff === 1 branch is a no-op labeled "Contributed yesterday, hasn't contributed today yet" — but at a midnight cron daysDiff === 1 actually means the user missed all of yesterday. the streak stays intact and can even keep growing while the user contributes only every other day.
The Problem
src/inngest/karma.ts lines 215-297. cron trigger is "0 0 * * *" (daily midnight), so now ≈ todayMidnight. inside the loop:
const todayMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();
const activeTimestamp = new Date(user.lastContributionAt).getTime();
const daysDiff = Math.floor((todayMidnight - activeTimestamp) / oneDayMs);
if (daysDiff === 0) {
// award streak_bonus, increment currentStreak
} else if (daysDiff >= 2) {
// reset currentStreak to 0
} else if (daysDiff === 1) {
// Valid trailing active window path (Contributed yesterday, hasn't contributed today yet)
skippedNoOp++;
}
trace: user contributes Monday 12:00 PM. Tuesday 00:00 cron: daysDiff = floor(12h / 24h) = 0 -> awards streak, streak=6. user does nothing on Tuesday. Wednesday 00:00 cron: daysDiff = floor(36h / 24h) = 1 -> skippedNoOp -> streak stays 6. Wednesday 08:00 the user contributes. Thursday 00:00 cron: daysDiff = floor(16h / 24h) = 0 -> awards streak, streak=7.
user grew streak from 5 to 7 while contributing only Monday and Wednesday — missing all of Tuesday. the comment on the daysDiff === 1 branch is inverted: contributing yesterday actually yields daysDiff === 0 at a midnight cron because yesterday's timestamp (e.g. Tue 08:00) is within the last 24h relative to today-midnight.
concrete failure: this corrupts the currentStreak field that gates streak_days_* badges in checkAndAwardBadges and leaderboards. every "streak" milestone can be earned while contributing every other day. only 3+ full-day gaps correctly reset the counter.
Proposed Fix
- treat any
daysDiff >= 1 as a streak break (or equivalently, daysDiff !== 0). since the midnight cron guarantees daysDiff === 0 is the only "contributed within the last full day" case, collapse the two else-if branches into one reset branch
- update the comment to reflect actual semantics
- mirror the same-day ledger idempotency guard already used for the
karmaTransactionsTable insert so the reset write is applied at most once per gap
I would like to work on this under GSSoC 26. please assign!
for labels i think gssoc + type:bug + level:advanced fits here.
Description
while reading through the daily streak processor i noticed the
daysDiff === 1branch is a no-op labeled "Contributed yesterday, hasn't contributed today yet" — but at a midnight crondaysDiff === 1actually means the user missed all of yesterday. the streak stays intact and can even keep growing while the user contributes only every other day.The Problem
src/inngest/karma.tslines 215-297. cron trigger is"0 0 * * *"(daily midnight), sonow ≈ todayMidnight. inside the loop:trace: user contributes Monday 12:00 PM. Tuesday 00:00 cron:
daysDiff = floor(12h / 24h) = 0-> awards streak, streak=6. user does nothing on Tuesday. Wednesday 00:00 cron:daysDiff = floor(36h / 24h) = 1-> skippedNoOp -> streak stays 6. Wednesday 08:00 the user contributes. Thursday 00:00 cron:daysDiff = floor(16h / 24h) = 0-> awards streak, streak=7.user grew streak from 5 to 7 while contributing only Monday and Wednesday — missing all of Tuesday. the comment on the
daysDiff === 1branch is inverted: contributing yesterday actually yieldsdaysDiff === 0at a midnight cron because yesterday's timestamp (e.g. Tue 08:00) is within the last 24h relative to today-midnight.concrete failure: this corrupts the
currentStreakfield that gatesstreak_days_*badges incheckAndAwardBadgesand leaderboards. every "streak" milestone can be earned while contributing every other day. only 3+ full-day gaps correctly reset the counter.Proposed Fix
daysDiff >= 1as a streak break (or equivalently,daysDiff !== 0). since the midnight cron guaranteesdaysDiff === 0is the only "contributed within the last full day" case, collapse the two else-if branches into one reset branchkarmaTransactionsTableinsert so the reset write is applied at most once per gapI would like to work on this under GSSoC 26. please assign!
for labels i think gssoc + type:bug + level:advanced fits here.