PR #427 introduced ORBIT0004 (raw DateTime.UtcNow for user-facing dates is a build error). The 52 pre-existing sites below (50 #pragma warning disable ORBIT0004 blocks; adjacent sites share a block) were measured with a real analyzer-enabled build and exempted because each is a deliberate UTC instant or a deliberate UTC-date bucket, not a user-facing date. Every pragma's WHY comment links this issue.
This ledger exists so each site keeps an explicit justification and can be re-audited. If any site's justification stops holding, fix the site and drop its pragma. One site found mischaracterized in review (ProfileController data-export filename) was already fixed properly with IUserDateService instead of a pragma and is not listed here.
Legend: instant = UTC moment used for expiry/TTL/cutoff/audit-timestamp math (timezone-correct by definition). bucket = UTC calendar-date used as a widened prefetch window or a UTC-keyed dedupe/aggregation key, with the per-user date still computed via TimeZoneInfo/IUserDateService downstream.
Orbit.Api
Controllers/SyncController.cs (2 sites, instant): sync-window guard against since and the ServerTimestamp field of the sync envelope; wire-protocol UTC instants.
OAuth/OAuthAuthorizationStore.cs (3 sites, instant): OAuth authorization-code CreatedAt stamp, code-expiry check, and expired-entry sweep cutoff.
Orbit.Application
Auth/Commands/RequestAccountDeletionCommand.cs (2 sites, instant): verification-code resend throttle elapsed math and VerificationEntry creation stamp.
Auth/Commands/SendCodeCommand.cs (4 sites, instant): same VerificationEntry throttle/TTL instants for send-code (including test-account and smoke-code paths).
Calendar/Commands/DismissCalendarSuggestionCommand.cs (1 site, instant): MarkDismissed(now) audit timestamp.
Habits/Commands/BulkCreateHabitsCommand.cs (1 site, instant): MarkImported(habitId, now) ImportedAtUtc audit timestamp for calendar suggestions.
Waitlist/Commands/JoinWaitlistCommand.cs (1 site, instant): 60-second resend-throttle elapsed math against the cached last-sent instant.
Orbit.Infrastructure
AI/AiUsageRecorder.cs (1 site, bucket): UTC-day key for the AiUsageDaily cost-aggregation row.
Persistence/OrbitDbContext.cs (1 site, instant): UpdatedAtUtc stamping for all tracked ITimestamped entities in SaveChangesAsync.
Services/AccountDeletionService.cs (3 sites: 2 instant, 1 bucket): scheduled-deletion due check, ProcessedRequest retention cutoff, and the 90-day UTC-date purge cutoff.
Services/AgentStepUpService.cs (3 sites, instant): step-up challenge cooldown boundary, challenge TTL, and CanVerify expiry check.
Services/AiUsageSummaryService.cs (1 site, bucket): UTC "yesterday" key for the daily AI-cost summary log.
Services/AuthSessionService.cs (5 sites, instant): session issue/refresh/revoke instants and refresh-token expiry math.
Services/BackgroundServiceHealthCheck.cs (2 sites, instant): liveness tick stamp and elapsed-since-last-tick math.
Services/GoalDeadlineNotificationService.cs (1 site, bucket): widened UTC streak-lookback prefetch window; per-user today comes from TimeZoneInfo.ConvertTimeFromUtc afterwards.
Services/GooglePlayBillingService.cs (2 sites, instant): Play subscription expiry fallback and validity comparison.
Services/HabitDueDateAdvancementService.cs (1 site, bucket): widened UTC "yesterday" prefetch window; per-user advancement uses the converted user clock.
Services/JwtTokenService.cs (1 site, instant): JWT Expires claim.
Services/PendingAgentOperationStore.cs (1 site, instant): pending-operation usability/expiry check.
Services/PendingClarificationStore.cs (2 sites, instant): clarification TTL stamp and expiry sweep.
Services/PlayNotificationCleanupService.cs (2 sites, instant): Play/Stripe processed-event retention cutoffs.
Services/ProactiveCheckinSchedulerService.cs (1 site, bucket): UTC-date dedupe key for SentProactiveCheckin; per-user send timing uses the converted user clock.
Services/ReminderSchedulerService.cs (6 sites, bucket): widened UTC-date prefetch windows (min/max local date across all timezones) and UTC-date dedupe keys; per-user reminder timing uses the converted user clock.
Services/SlipAlertSchedulerService.cs (1 site, bucket): UTC-date week key for SentSlipAlert dedupe.
Services/StreakFreezeAutoActivationService.cs (1 site, bucket): widened UTC "yesterday" prefetch window; per-user freeze decision uses the converted user clock.
Services/StripeBillingService.cs (1 site, instant): CurrentPeriodEnd fallback instant.
Services/SyncCleanupService.cs (2 sites, instant): tombstone and suggestion retention cutoffs.
Totals: 38 instant + 14 bucket = 52 sites in 27 files (ProfileController's former 53rd site was fixed, not exempted).
Origin: orbit-ui-mobile REBUILD.md 6.1.2 gap 2 (the old csharp-tz hook did not cover Orbit.Infrastructure/Orbit.Api). Enforcement: src/Orbit.Analyzers/UtcNowUserFacingDateAnalyzer.cs, CI-only visibility (local in-box csc skips it with CS9057).
PR #427 introduced ORBIT0004 (raw
DateTime.UtcNowfor user-facing dates is a build error). The 52 pre-existing sites below (50#pragma warning disable ORBIT0004blocks; adjacent sites share a block) were measured with a real analyzer-enabled build and exempted because each is a deliberate UTC instant or a deliberate UTC-date bucket, not a user-facing date. Every pragma's WHY comment links this issue.This ledger exists so each site keeps an explicit justification and can be re-audited. If any site's justification stops holding, fix the site and drop its pragma. One site found mischaracterized in review (ProfileController data-export filename) was already fixed properly with
IUserDateServiceinstead of a pragma and is not listed here.Legend: instant = UTC moment used for expiry/TTL/cutoff/audit-timestamp math (timezone-correct by definition). bucket = UTC calendar-date used as a widened prefetch window or a UTC-keyed dedupe/aggregation key, with the per-user date still computed via
TimeZoneInfo/IUserDateServicedownstream.Orbit.Api
Controllers/SyncController.cs(2 sites, instant): sync-window guard againstsinceand theServerTimestampfield of the sync envelope; wire-protocol UTC instants.OAuth/OAuthAuthorizationStore.cs(3 sites, instant): OAuth authorization-code CreatedAt stamp, code-expiry check, and expired-entry sweep cutoff.Orbit.Application
Auth/Commands/RequestAccountDeletionCommand.cs(2 sites, instant): verification-code resend throttle elapsed math and VerificationEntry creation stamp.Auth/Commands/SendCodeCommand.cs(4 sites, instant): same VerificationEntry throttle/TTL instants for send-code (including test-account and smoke-code paths).Calendar/Commands/DismissCalendarSuggestionCommand.cs(1 site, instant):MarkDismissed(now)audit timestamp.Habits/Commands/BulkCreateHabitsCommand.cs(1 site, instant):MarkImported(habitId, now)ImportedAtUtc audit timestamp for calendar suggestions.Waitlist/Commands/JoinWaitlistCommand.cs(1 site, instant): 60-second resend-throttle elapsed math against the cached last-sent instant.Orbit.Infrastructure
AI/AiUsageRecorder.cs(1 site, bucket): UTC-day key for the AiUsageDaily cost-aggregation row.Persistence/OrbitDbContext.cs(1 site, instant):UpdatedAtUtcstamping for all tracked ITimestamped entities in SaveChangesAsync.Services/AccountDeletionService.cs(3 sites: 2 instant, 1 bucket): scheduled-deletion due check, ProcessedRequest retention cutoff, and the 90-day UTC-date purge cutoff.Services/AgentStepUpService.cs(3 sites, instant): step-up challenge cooldown boundary, challenge TTL, and CanVerify expiry check.Services/AiUsageSummaryService.cs(1 site, bucket): UTC "yesterday" key for the daily AI-cost summary log.Services/AuthSessionService.cs(5 sites, instant): session issue/refresh/revoke instants and refresh-token expiry math.Services/BackgroundServiceHealthCheck.cs(2 sites, instant): liveness tick stamp and elapsed-since-last-tick math.Services/GoalDeadlineNotificationService.cs(1 site, bucket): widened UTC streak-lookback prefetch window; per-user today comes fromTimeZoneInfo.ConvertTimeFromUtcafterwards.Services/GooglePlayBillingService.cs(2 sites, instant): Play subscription expiry fallback and validity comparison.Services/HabitDueDateAdvancementService.cs(1 site, bucket): widened UTC "yesterday" prefetch window; per-user advancement uses the converted user clock.Services/JwtTokenService.cs(1 site, instant): JWTExpiresclaim.Services/PendingAgentOperationStore.cs(1 site, instant): pending-operation usability/expiry check.Services/PendingClarificationStore.cs(2 sites, instant): clarification TTL stamp and expiry sweep.Services/PlayNotificationCleanupService.cs(2 sites, instant): Play/Stripe processed-event retention cutoffs.Services/ProactiveCheckinSchedulerService.cs(1 site, bucket): UTC-date dedupe key for SentProactiveCheckin; per-user send timing uses the converted user clock.Services/ReminderSchedulerService.cs(6 sites, bucket): widened UTC-date prefetch windows (min/max local date across all timezones) and UTC-date dedupe keys; per-user reminder timing uses the converted user clock.Services/SlipAlertSchedulerService.cs(1 site, bucket): UTC-date week key for SentSlipAlert dedupe.Services/StreakFreezeAutoActivationService.cs(1 site, bucket): widened UTC "yesterday" prefetch window; per-user freeze decision uses the converted user clock.Services/StripeBillingService.cs(1 site, instant):CurrentPeriodEndfallback instant.Services/SyncCleanupService.cs(2 sites, instant): tombstone and suggestion retention cutoffs.Totals: 38 instant + 14 bucket = 52 sites in 27 files (ProfileController's former 53rd site was fixed, not exempted).
Origin: orbit-ui-mobile REBUILD.md 6.1.2 gap 2 (the old
csharp-tzhook did not cover Orbit.Infrastructure/Orbit.Api). Enforcement:src/Orbit.Analyzers/UtcNowUserFacingDateAnalyzer.cs, CI-only visibility (local in-box csc skips it with CS9057).