[Review] computeCyclePhase / isoDate anchors on UTC midnight — drifts one calendar day for negative-UTC users #177
Labels
No labels
blocked:depends-p1
blocked:gate-research
blocked:lint-failed
blocked:needs-decision
blocked:needs-human
blocked:verify-failed
bug
data-loss
documentation
enhancement
feature-request
in-progress
needs-decompose
needs-triage
pwa
quickfix
security
security/high
security/medium
test
test-coverage
triage-approved
vault
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Mark/kimi_agent_kin_app_sync#177
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Finding
src/lib/intimate-state-engine.ts:19-30:dateOnlyproduces UTC midnight, thentoISOString()displays in UTC. For a user in UTC-7 (PDT) enteringlastPeriodStart = "2026-03-15"as a local date, the engine stores2026-03-15T00:00:00ZandisoDatedisplays"2026-03-15"— fine.But if the user enters
"2026-03-15T23:30 local PDT"via any UI control that produces local ISO strings, the storage is2026-03-16T06:30:00Z,dateOnlybecomes2026-03-16T00:00:00Z, and the user sees their cycle phase anchored on March 16 (UTC date) even though they entered March 15 (local).The reverse also holds: late-evening local-time entries shift forward by one UTC day.
Internally,
diffDays = floor((ref.getTime() - last.getTime()) / DAY_MS)is consistent because it uses absolute timestamps. The bug is purely in the display ofphaseStart/phaseEndand the user's mental model of which day their cycle started.Repro
In a timezone west of UTC (PDT, PST, AKST, HST):
person.cycleTracking = { enabled: true, lastPeriodStart: "2026-03-15T23:30", cycleLength: 28, lutealPhaseLength: 14 }(a string captured late in the local evening).buildCycleInsight(person, new Date("2026-03-22T20:00 local PDT")).phaseStartreports"2026-03-16". The user entered March 15.Suggested fix
dateOnlyusing local-midnight components (new Date(d.getFullYear(), d.getMonth(), d.getDate())) instead ofDate.UTC(...).vi.setSystemTimewith a non-UTC zone, or parameterize the helper).Severity
Medium. UX-visible bug for users west of UTC (i.e. North America). The internal day-of-cycle math is correct, but the displayed phase boundaries drift.
Discovered by
Manual code review pass over #168, 2026-09-14.