Development Progress
Every commit, every fix, every feature — a detailed log of ConvoAct's evolution from day one.
March 30, 2026
Today iOSv1.2.0 (Build 6) — Resubmitted for Review
v1.2.0Resubmitted after fixing the 4 root causes behind Build 5’s blank screen on iPad Air (M3). Fixes: removed SplashView’s opacity-0 initial state that could stick when animations cancelled, forced NavigationSplitView to .detailOnly on appear (was collapsing the detail column in portrait), added .layoutPriority(1) to the onboarding TabView (was sized to zero), and set a proper UILaunchScreen background color in Info.plist. Also added UISupportedInterfaceOrientations~ipad and startup diagnostic breadcrumbs via Sentry.
Sentry Monitoring Expanded
v1.2.0Discovered that SENTRY_DSN was missing from Info.plist — Sentry was completely disabled in production. Fixed by adding the DSN and moving Sentry init to AppDelegate.didFinishLaunchingWithOptions for proper session tracking. Added startup diagnostic breadcrumbs that log which root view rendered, crash-free session monitoring, and expanded error capture across the launch sequence, screen transitions, and view lifecycle events.
v1.2.0 (Build 5) — Rejected by Apple (Guideline 2.1)
v1.2.0Apple rejected v1.2.0 Build 5 under Guideline 2.1(a) (App Completeness) on iPad Air 11-inch (M3) running iPadOS 26.3.1. The app launched to a blank beige/cream screen matching Color.appBackground — the app was running but content wasn’t rendering. Four root causes identified: SplashView mascot opacity stuck at 0 from animation cancellation, NavigationSplitView collapsing the detail column in portrait, onboarding TabView sized to zero, and empty UILaunchScreen dictionary with no background color.
March 27, 2026
iOSv1.2.0 (Build 5) — Resubmitted for Review
v1.2.0Resubmitted after fixing iPad crash that caused rejection. SensorKit (iPhone-only) was being auto-linked as a required framework by Swift, overriding the -weak_framework linker flag and causing a DYLD crash on iPad Air (M3) running iPadOS 26.4. Fixed by adding -Xfrontend -disable-autolink-framework to OTHER_SWIFT_FLAGS so only the explicit weak link applies.
v1.2.0 — Rejected by Apple (Guideline 2.1a)
v1.2.0Apple rejected v1.2.0 under Guideline 2.1a (App Completeness). The app crashed at launch on iPad Air (M3) because Swift’s import SensorKit auto-linked SensorKit as a required framework (LC_LOAD_DYLIB), overriding the intended -weak_framework flag. SensorKit is iPhone-only and unavailable on iPad, causing a DYLD load failure.
v1.2.0 — Submitted for Review
v1.2.0Major update submitted to App Store review. 15 new features, 11 bug fixes, 9 improvements, and 91 stability fixes across two comprehensive audits. Adds companion mascot, Game Center, achievement gallery, clinical assessments, on-device predictions, critical medication alerts, CloudKit sync, and more.
New Features (15)
- Companion Mascot: A friendly robot that reacts to your day — adapts its expression based on your energy, burnout level, and time of day
- Achievement Gallery: 22 badges with progress tracking. Earned badges glow, unearned ones show how close you are
- Game Center: Opt-in leaderboards (focus time, tasks, streaks, XP) and 22 achievements synced with Apple
- Data Export: Share mood, medication adherence, habits, and focus history with your therapist as CSV or PDF reports
- Batch Quick-Log: Log mood, water, and medication in one sheet — 3 taps total, designed for low-energy days
- Challenges & Referrals: Weekly challenges with XP rewards. Invite friends with your referral code and both earn bonuses
- Progressive Unlocking: New users start with core features and unlock more as they build consistency. Power users can unlock everything in Settings
- Smart Notifications: Daily budget (max 5), timing based on your habits, sleep quiet hours, and gentle re-engagement
- Clinical Assessments: Validated PHQ-9, GAD-7, and ASRS-v1.1 screening with score history and trend charts
- On-Device Predictions: Mood prediction, task duration estimation, and burnout risk trending — all processed on your device
- Year in Pixels: Calendar heatmap showing your mood for every day at a glance
- Critical Medication Alerts: Time-sensitive medication reminders can now bypass Do Not Disturb
- CloudKit Sync: Optional iCloud sync as a privacy-first alternative
- Live Step Tracking: Real-time steps and activity classification from CoreMotion
- Shareable Achievement Cards: Share milestone cards to social media or messages
Bug Fixes (11)
- Fixed sign-out not clearing data from 16 services — switching accounts no longer shows stale data
- Fixed authentication race condition that could deadlock concurrent requests
- Fixed memory leak in voice dictation audio engine
- Fixed medication notifications ignoring the daily budget on some paths
- Fixed challenge progress not recording across 7 completion flows
- Fixed cycle tracking phase calculation producing incorrect day counts
- Fixed SyncEngine losing data when a delete arrives immediately after a create
- Fixed widget dates displaying incorrectly due to mismatched encoding
- Fixed stale Focus live activities persisting after app restart
- Fixed HealthKit queries not checking authorization (12 functions)
- Fixed encrypted offline data becoming unreadable after encryption state changes
Improvements (9)
- Smart task recommendations cached — only recomputed when data changes
- Plan tab task grouping pre-computed instead of recalculated every render
- AI task enrichment timeout reduced from 15s to 5s
- SyncEngine retries automatically with fresh auth token on 401 errors
- SyncEngine offline queue replay moved off main thread to prevent hangs
- Settings rows now read as single accessible elements in VoiceOver
- Memory-adaptive caching scales down when device memory is low
- Medication loading throttled to prevent redundant fetches
- iPad and Mac keyboard shortcuts for common actions
Stability & Performance
- 91 fixes across two comprehensive audits covering sync, performance, widgets, accessibility, and data safety
- Hardened offline sync with auth retry, background replay, crash protection, and payload validation
- Adaptive resource management using real-time memory checks
- Critical startup tasks prioritized for faster launch
March 26, 2026
iOSCritical Alerts Entitlement Approved by Apple
v1.2.0Apple granted the com.apple.developer.usernotifications.critical-alerts entitlement. Medication reminders can now bypass Do Not Disturb, ensuring users never miss a dose even in Focus or Sleep modes. SensorKit remains excluded pending separate research entitlement approval.
March 25, 2026
iOSv1.1.1 — Approved by Apple
v1.1.1v1.1.1 approved by Apple and now live on the App Store. This release includes 18 rounds of reliability audits, 7 Apple framework integrations, full 7-language localization, 40 unit tests, and Sentry health monitoring. The March 25 development work (mascot system, Game Center, 10 new frameworks, competitive edge features) will ship in the next version.
Version Bump to v1.2.0 (Build 1)
v1.2.0Bumped MARKETING_VERSION from 1.1.1 → 1.2.0 and CURRENT_PROJECT_VERSION from 3 → 1 across all 5 targets. Ready for submission with all March 25 development work.
Mascot System & Accessibility Polish
v1.2.0SwiftUI robot mascot with 6 expressions and 22 placements across the app. Accessibility audit fixes for improved VoiceOver support and dynamic type.
Highlights
- Robot Mascot: New SwiftUI mascot component with 6 expressions (happy, thinking, celebrating, sleeping, confused, encouraging)
- 22 Placements: Mascot appears contextually across onboarding, empty states, achievements, focus sessions, and more
- Accessibility Audit: Fixed VoiceOver labels, dynamic type scaling, contrast ratios, and focus order across 27 modified files
Game Center Integration
v1.2.0Opt-in Game Center support with 22 achievements and 4 leaderboards for social competition and motivation.
Highlights
- 22 Achievements: Unlock achievements for focus streaks, task completion milestones, wellness check-ins, and more
- 4 Leaderboards: Compete with friends on focus time, tasks completed, habit streaks, and wellness scores
- Opt-in: Game Center integration is entirely optional — enable from Settings
10 Apple Framework Integrations
v1.2.0Integrated 10 additional Apple frameworks: CoreMotion, CoreML, Accelerate, ResearchKit, Compression, CoreTransferable, RegexBuilder, CloudKit, SwiftData, and Critical Alerts.
Frameworks
- CoreMotion: Step counting and activity recognition for wellness insights
- CoreML: On-device machine learning for personalized recommendations
- Accelerate: High-performance math for data analysis and trend computation
- ResearchKit: Structured surveys and wellness questionnaires
- Compression: Efficient data compression for sync and export
- CoreTransferable: Drag-and-drop and share sheet support for tasks and notes
- RegexBuilder: Type-safe input validation and parsing
- CloudKit: Cloud-backed sync for cross-device continuity
- SwiftData: Modern persistence layer for local caching
- Critical Alerts: High-priority medication reminders that bypass Do Not Disturb
Competitive Edge & 5-Star Enhancement — Phases 1–3
v1.2.0Major feature expansion: Batch Quick Log, Achievement Gallery, Data Export, Year in Pixels, Feature Unlock system, Activity Feed, Challenges, Referrals, and Notification Orchestration.
Phase 1 — Quick Wins
- Batch Quick Log: Log multiple habits, medications, and tasks in a single swipe
- Achievement Gallery: Visual collection of all unlocked achievements with progress tracking
- Data Export: Export your data as CSV or JSON for personal analysis
Phase 2 — Engagement
- Year in Pixels: Color-coded calendar heatmap showing your daily mood and productivity
- Feature Unlock: Progressive feature discovery as you build consistency
- Activity Feed: Timeline of recent actions and milestones for self-reflection
Phase 3 — Social & Growth
- Challenges: Time-limited goals (e.g., “7-day focus streak”) with rewards
- Referrals: Invite friends and earn premium feature unlocks
- Notification Orchestration: Intelligent notification scheduling that respects focus time, sleep, and user preferences
Second Comprehensive Audit — 44 Fixes Across 6 Domains
v1.2.0Full-depth second audit covering performance bottlenecks, SyncEngine safety, Widget/LiveActivity correctness, accessibility gaps, UserDefaults hygiene, and resource management. 44 issues fixed across 33 files.
Performance (7 fixes)
- TaskViewModel
smartRecommendedTaskscaching with cache key invalidation - PlanTaskSectionsView pre-computed grouping (reads ViewModel instead of filtering per render)
- MoodTrendsView dedup (single
moodTrendData()call shared across charts) - Widget toggle parallelized with
withTaskGroup - Spotlight indexing immediate (removed artificial delay)
- Startup task prioritization (critical vs background)
- AchievementGallery moved OfflineStore load from computed property to async
.task{}
SyncEngine Safety (6 fixes)
- 401 retry with automatic token refresh in
batchUpsert() - WAL replay moved from synchronous init to async background task
- Delete-after-create dedup flushes WAL immediately (not 0.5s debounce)
- Default retry count reduced 10 → 3
- Payload size validation (5MB limit)
- Encoding errors escalated with full entity context (MedicationRepository, CycleRepository)
Widget & LiveActivity (5 fixes)
.iso8601date encoding/decoding strategy in WidgetDataProviderToggleTaskIntentcount clamped to valid rangeFocusLiveActivity.cleanupStaleActivities()at launch- Unknown enum fallbacks via custom decoder (ActivityFeedItem, Medication, MoodCheckin)
Accessibility (3 fixes)
- SettingsView
settingsRow()/settingsToggleRow()combined accessible elements - Decorative icons hidden from VoiceOver across Settings and ClinicalAssessment
Safety & Resource Management (6 fixes)
- OfflineStore disk space pre-check (<10MB warns via Sentry)
- Encryption migration fallback (tries both decode paths)
- Adaptive cache sizing via
os_proc_available_memory() - OnDeviceAIService LRU session pruning when memory <100MB
- MedicationViewModel 30-second
loadAll()dedup throttle - Array caps on cached collections
UserDefaults & Intents (6 fixes)
- 9 new
UserDefaultsKeyconstants centralized in Constants.swift - Raw strings replaced across 6 files (AppState, DailyAdaptive, BurnoutDetector, Translation, Feedback, Privacy)
- IntentDonationManager parameters wired for Siri learning
- AI enrichment timeout reduced 15s → 5s
- ChallengeService time format localized
Comprehensive Audit — 47 Fixes Across 8 Domains
v1.2.0Full-depth audit covering data safety, concurrency, wiring, HealthKit, notifications, navigation, persistence, and logic. 47 issues fixed across 50 files.
Sign-out Data Cleanup (16 services)
- Added
clearUserData()to 16 services (RewardService, PredictionService, ReferralService, CoreMotionService, CalendarSyncService, and 11 more) - Wired all cleanups from
AppState.signOut() - Fixed CycleTrackingView + MovementTrackingView missing AppState injection
Concurrency (7 fixes)
- SupabaseService continuation race (array guard)
- VoiceTranscription retain cycle (
[weak self]) - SensorKit delegate overwrite (local per fetch)
- Medication attachment URL race (NSLock)
- ContactVM searchTask race (NSLock)
- Task.isCancelled guards + OnDeviceAI prewarm Task.detached
Medication & Notifications (5 fixes)
- Deactivation now cancels notifications + reloads widget
- Budget enforcement on all scheduling paths
- Scheduling race guard + calendar trigger quiet hours (10PM–7AM)
Feature Wiring (4 fixes)
- ChallengeService progress wired in 7 flows
- GameCenter leaderboard submissions + XP conversion
- PredictionService wired to WellnessVM + TaskVM
Navigation (3 fixes)
- SharedGoal/Invite tab routing
- FocusDeepLinkBridge handlers
- DataRefreshBus observers
HealthKit & Frameworks (6 fixes)
- Critical-alert + SensorKit entitlements
- CoreMotion launch start + HKObserverQuery lifecycle
- State of Mind write auth + 12 read function auth guards
- CloudKit pre-flight check
Data Persistence (2 fixes)
- MessageRepository merge-by-ID
- OfflineStore encryption error surfacing
Logic (4 fixes)
- CycleVM phase calculation + daysUntilNextPeriod
- AppDelegate observer token + GroupActivity task tracking
Fix 2 Xcode Warnings
v1.2.0Resolved 2 Xcode compiler warnings: removed redundant MainActor.run call and fixed GameCenter dismiss handler isolation for strict concurrency compliance.
Remove Entitlements Pending Apple Approval
v1.2.0Temporarily removed critical-alerts and sensorkit entitlements from the entitlements file pending Apple approval. Ensures the app builds and runs cleanly without unapproved entitlements blocking submission.
March 24, 2026
iOSv1.1.1 — Resubmitted to App Store
v1.1.1Resubmitted after developer-rejection. Includes 7 Apple framework integrations, Rounds 17–18, localization (7 languages), Xcode 17.3 update, Sentry monitoring, 40 unit tests, 18 audit rounds total.
New Features
- Calendar Sync: Medication reminders and completed focus sessions now sync to your iOS Calendar automatically, with frequency-aware recurrence (daily, weekly, as-needed)
- Voice Dictation: Tap the mic button in journal entries to dictate instead of type, with proper permission handling and error feedback
- Focus Together SharePlay: Start shared focus sessions with friends over FaceTime
- Auto-Translate: AI-generated wellness insights, coaching, and chat are translated to your device language (iOS 18+). New toggle in Settings to opt out.
- Data Detection: Dates, links, and phone numbers are automatically highlighted in messages — works on iOS 17+ (NSDataDetector fallback) and iOS 26+ (DataDetection framework)
- Integrations Settings: New toggles for Calendar Sync, Auto-Translate, and SensorKit in Settings
- Enhanced Burnout Detection: 10-factor scoring model now includes “Digital Load” as a weighted factor (5%) combining device usage, ambient light, and typing intensity from SensorKit
- Purchase Integrity: App Attest verification for subscription purchases via Secure Enclave
- Health Baselines: Biological sex and age now read from Apple Health for better wellness baseline calculations
- Full Localization: App now available in 7 languages — Spanish, French, German, Portuguese (Brazil), Japanese, Hindi, and Chinese Simplified. All 1,784 UI strings and 11 permission descriptions translated. iOS automatically matches your phone language.
Bug Fixes & Reliability
- Fixed a crash when reading physical effort data from Apple Health on certain devices
- Fixed blank screen when switching between apps and returning to ConvoAct
- Fixed settings rows where tapping the arrow area didn’t navigate
- Fixed focus timer not updating correctly after returning from background
- Fixed AI chat messages that could be lost if saving failed
- Fixed task creation and Smart Create reliability issues
- Fixed data that could silently fail to sync after network errors
- Fixed SensorKit data being stale during burnout evaluation (now fetched fresh before scoring)
- Fixed habit streak data unavailable offline (now cached locally with automatic refresh)
- Fixed conversation creation failing silently when server read-back fails (now queues for retry)
- Eliminated multiple sources of “ghost data” where completed actions could revert on refresh
- Resolved all reported Sentry crash and error issues
Improvements
- Smoother app lock screen transition when returning from background
- Haptic feedback on pull-to-refresh across all main screens
- Haptic feedback on toggle switches in Settings
- Error messages now shown to user when background sync fails (previously silent)
- Widgets now refresh immediately after medication, habit, and task changes
- Confetti celebration when completing a focus session
- Streak milestone celebration (toast + confetti) for habit streaks at 3, 5, 7, 14, 30, 60, 90, 100, and 365 days
- Enriched empty states with helpful suggestions when no habits are set up
- Guest mode now works fully offline with no server calls
- Guest data migrates seamlessly when creating an account
- Unsaved changes warning when editing a task — prevents accidental data loss
- Refresh button on Focus Readiness screen to pull latest health data
- Smooth numeric animation on multi-step wizard progress indicators
Stability & Performance
- 18 rounds of comprehensive data reliability audits across all sync paths
- Hardened offline-first sync pipeline with automatic retry for failed operations
- Reduced app hang frequency through optimized view rendering
- Enhanced Sentry monitoring: CPU profiling, MetricKit diagnostics, time-to-display tracking, and background task instrumentation
- 40 unit tests covering all framework integrations
Xcode 17.3 Recommended Settings Update
v1.1.1Updated project build settings to Xcode 17.3 recommended defaults.
Full Localization — 7 Languages
v1.1.11,784 UI strings + 11 Info.plist keys translated into es, fr, de, pt-BR, ja, hi, zh-Hans. ~12,565 translations total.
Languages
- Spanish (es)
- French (fr)
- German (de)
- Portuguese — Brazil (pt-BR)
- Japanese (ja)
- Hindi (hi)
- Chinese Simplified (zh-Hans)
Scope
- 1,784 UI strings per language
- 11 Info.plist keys per language
- ~12,565 total translations
v1.1.1 Developer-Rejected & Rebuilt with 7 Apple Framework Integrations
v1.1.1Developer-rejected before Apple review. Rebuilt with 7 new Apple services: CalendarSync, AppAttest, Translation, VoiceTranscription, DataDetection, SensorKit, GroupActivity.
New Apple Framework Integrations (7)
- CalendarSync — Calendar event syncing
- AppAttest — Device attestation for security
- Translation — On-device translation service
- VoiceTranscription — Voice-to-text transcription
- DataDetection — Automatic data detection in text
- SensorKit — Sensor data for burnout detection
- GroupActivity — SharePlay group activities
Scope
- 8 new files created
- 14 existing files modified
- 30 new unit tests added
Round 18b — SensorKit Staleness Fix & Translation Toggle
v1.1.1Fixed SensorKit data staleness issue and added auto-translate opt-out toggle.
Round 18 — Framework Integration Hardening & Reach Expansion
v1.1.1Hardened newly integrated Apple frameworks. CalendarSync frequency fix, DataDetection iOS 17+ fallback, HKCharacteristicType reads, voice auth guard, BurnoutDetector SensorKit deepening, MessageThreadView DataDetection wiring.
Fixes (8)
- CalendarSync frequency capping
- DataDetection iOS 17+ fallback handling
- HKCharacteristicType reads hardened
- Voice auth guard added
- BurnoutDetector SensorKit deepening
- MessageThreadView DataDetection wiring
- Framework integration edge cases resolved
- Reach expansion for broader device compatibility
Round 17 — Comprehensive Reliability Audit
v1.1.119 fixes across 22 files: 5 critical, 4 high, 3 medium, 7 low severity issues resolved.
Severity Breakdown
- Critical (5) — Data integrity and crash fixes
- High (4) — Sync reliability improvements
- Medium (3) — UX and error handling
- Low (7) — Polish and edge cases
March 22, 2026
iOSv1.1.1 — Submitted for Review
v1.1.1v1.1.1 submitted to Apple for approval. This release covers everything since v1.1.0 (deployed Mar 20, 2026).
Bug Fixes & Reliability
- Fixed a crash when reading physical effort data from Apple Health on certain devices
- Fixed blank screen when switching between apps and returning to ConvoAct
- Fixed settings rows where tapping the arrow area didn’t navigate
- Fixed focus timer not updating correctly after returning from background
- Fixed AI chat messages that could be lost if saving failed
- Fixed task creation and Smart Create reliability issues
- Fixed data that could silently fail to sync after network errors
- Eliminated multiple sources of “ghost data” where completed actions could revert on refresh
- Resolved all reported Sentry crash and error issues
Improvements
- Smoother app lock screen transition when returning from background
- Haptic feedback on pull-to-refresh across all main screens
- Haptic feedback on toggle switches in Settings
- Error messages now shown to user when background sync fails (previously silent)
- Widgets now refresh immediately after medication, habit, and task changes
- Confetti celebration when completing a focus session
- Streak milestone celebration (toast + confetti) for habit streaks at 3, 5, 7, 14, 30, 60, 90, 100, and 365 days
- Enriched empty states with helpful suggestions when no habits are set up
- Guest mode now works fully offline with no server calls
- Guest data migrates seamlessly when creating an account
Stability
- 16 rounds of comprehensive data reliability audits across all sync paths
- Hardened offline-first sync pipeline with automatic retry for failed operations
- Reduced app hang frequency through optimized view rendering
Sentry Audit — Fix 3 Crashes, Resolve All 52 Issues
v1.1.1Full Sentry audit of all 52 unresolved issues. Fixed 3 bugs in code, resolved or ignored the rest. Zero unresolved issues remaining.
Code Fixes (3)
- APPLE-IOS-K — HealthKit physical effort unit crash (3 users, 6 events, fatal) —
is(compatibleWith:)returnstrueforkcal/hr·kgvsappleEffortScoreon some devices (Apple bug), butdoubleValue(for:)then throws an uncatchableNSException. Added secondary unit description string check before callingdoubleValue(for:). - APPLE-IOS-M/S/1G — Blank screen on app switch (3 users) —
checkAutoLock()was settingisLocked = truewithoutwithAnimation, so LockScreenView’s.transition(.opacity)never animated. Users saw a jarring blank overlay. Wrapped inwithAnimation. - APPLE-IOS-P — Settings arrow tap target (1 user) —
.buttonStyle(.plain)on NavigationLinks limited hit area to visible content only. Added.contentShape(Rectangle())to make full row tappable.
Triage Summary (52 Total)
- 47 resolved (3 code-fixed, 7 already fixed in prior rounds, 30 transient app hangs, 7 server/OS/old-build)
- 5 ignored (unlabeled events with no actionable data)
- 0 unresolved remaining
Files Changed (3)
Services/HealthKit/HealthKitManager+Activity.swift
App/AppState.swift
Views/Settings/SettingsView.swift
Round 16 — Timer Bug, Ghost Data, Error Feedback & Celebration Polish
v1.1.1Comprehensive 3-agent audit of all unaudited ViewModels, Views, animation gaps, and stale data paths. All repositories passed clean.
Critical Fixes
- FocusView timer bug — Added
@Environment(\.scenePhase)+.onChange(of: scenePhase)handler. Without this, the timer didn’t recalculate from wall clock after backgrounding (FocusTogetherView had it, FocusView didn’t). - ChatViewModel AI message ghost data — When
messageRepo.createMessage()returns nil, the unsaved AI message was appended to UI but never persisted. Added SyncEngine enqueue fallback.
High & Medium Fixes
- MovementViewModel —
logWorkout()catch block only logged to Sentry but didn’t seterrorMessage. User saw optimistic success but sync failed silently. - Focus session confetti — Wired
.confettiCannon(trigger:)to FocusCelebrationRitual on session completion. - Habit streak milestone toast — Added
celebratedMilestoneproperty + toast overlay with confetti for streaks [3, 5, 7, 10, 14, 21, 30, 60, 90, 100, 365].
Low Fixes
- Pull-to-refresh haptic — Added
HapticManager.shared.trigger(.light)at end of.refreshablein PlanView, WellnessView, FocusView.
Files Changed (8)
Views/Focus/FocusView.swift
ViewModels/ChatViewModel.swift
ViewModels/MovementViewModel.swift
ViewModels/WellnessViewModel.swift
Views/Focus/SessionSummarySheet.swift
Views/Wellness/HabitTrackingView.swift
Views/Plan/PlanView.swift
Views/Wellness/WellnessView.swift
Round 15 — Widget Freshness, Error Haptics & UX Polish
v1.1.1Deep ViewModel audit found widget staleness across Medication and Habit operations, missing error haptics on failure paths, and a bare empty state in messaging.
Widget Freshness (9 Operations)
- MedicationViewModel — Added
WidgetCenter.shared.reloadAllTimelines()to:addMedication(),updateMedication(),takeMedication(),skipMedication(),removeMedication() - WellnessViewModel — Added
refreshWidgetData()calls to:createHabit(),incrementStreak(),updateHabit(),deactivateHabit()
Error Haptics (4 Catch Blocks)
- MedicationViewModel — Added
.errorhaptic toaddMedication(),takeMedication(),skipMedication()catch blocks - WellnessViewModel — Added error message to user in
incrementStreak()andupdateHabit()catch blocks
UX Polish
- MessageThreadView — Empty state with bubble icon and “Say hello to start the conversation!” instead of blank scroll
Files Changed (3)
ViewModels/MedicationViewModel.swift
ViewModels/WellnessViewModel.swift
Views/Messages/MessageThreadView.swift
Round 14 — Lower-Priority Audit & Wellness Empty State Polish
v1.1.1Systematic sweep of all remaining lower-priority items. Found 5 of 7 already resolved in prior rounds. Enriched habits empty state with gradient-stroked icon ring, motivational copy, and suggestion chips.
Implemented
- WellnessView habits empty state — Replaced minimal 3-line empty state with richer design: gradient-stroked icon ring with
.symbolEffect(.pulse)animation, motivational headline + body copy, suggestion chips (Drink Water, 10min Walk, Read) with colored icons, proper accessibility labels.
Already Resolved (5 Items)
- Guest migration string replacement → field-aware JSON: Done in Round 13
- SyncEngine refreshUpdatedAt() try? → Already has do/catch with Sentry
- Settings toggle haptics → Already done in Round 12
- AIHubView .refreshable → Already done in Round 13
- JournalView .refreshable → Already done in Round 13
Ghost Data Re-Audit
- 0 findings. All services properly enqueue to SyncEngine on both offline AND online server failure paths.
Files Changed (1)
Views/Wellness/WellnessView.swift
Round 13 — Migration Safety, Error Tracking & UX Polish
v1.1.1Clears all remaining audit backlog items: field-aware guest migration to prevent UUID rewriting in message content, SyncEngine error visibility, habits empty state, and missing pull-to-refresh on journal and AI chat.
Field-Aware Guest Migration (Data Integrity)
- OfflineStore.remapUserId() — Previously used blind
replacingOccurrences(of:with:)which would rewrite the guest UUID anywhere in JSON — including conversation text or another user’s ID. Rewritten to decode JSON, walk the object tree, and only rewrite known userId field keys (user_id,userId,from_user_id,to_user_id,creator_id,owner_id). - SyncEngine.remapUserId() — Same field-aware rewrite for both main queue and dead-letter queue.
Error Visibility & UX
- SyncEngine.refreshUpdatedAt() — Two
try?calls silently returned stale data on JSON failure. Converted to do/catch with Sentry warning logs. - WellnessView — Habits empty state enriched with leaf icon, heading, and “Tap the + above” subtext.
- JournalView — Added
.refreshablefor pull-to-refresh. - AIHubView — Added
.refreshableon message ScrollView.
Files Changed (5)
Services/OfflineStore.swift
Services/SyncEngine.swift
Views/Wellness/WellnessView.swift
Views/Wellness/JournalView.swift
Views/AIHub/AIHubView.swift
Round 12 Audit — Ghost Data, Error Swallowing, Widget Freshness & Toggle Haptics
v1.1.14-agent parallel audit covering ghost data, UX polish, notification/widget pipeline, and try? error swallowing. Confirmed 19+ entity repositories follow correct offline-first pattern.
Ghost Data Fixes (2 Critical)
- TaskRepository.createTasks() — Batch task creation saved locally, server insert fails → catch block logged to Sentry but did NOT enqueue to SyncEngine → all tasks vanish on next refresh. Fixed: added SyncEngine enqueue loop.
- TaskRepository.upsertTask() — Task upserted locally, server call had NO do/catch wrapper → failure throws without enqueue. Fixed: wrapped with SyncEngine enqueue.
Error Swallowing Fixes (2 High)
- ContactRepository.sendContactRequest() —
try? JSONSerialization.data()could silently fail, creating nil payload that SyncEngine would dead-letter. Fixed: do/catch with Sentry logging. - TaskRepository updateActualMinutes/updateEnergyCost — Server error path used
try? encoder.encode(). Fixed: do/catch withSentryErrorTracker.captureEncodingError().
Widget Freshness (3 Gaps Closed)
- WellnessViewModel.refreshWidgetData() — Updated UserDefaults but never called
WidgetCenter.shared.reloadAllTimelines(). Habit completions and mood logs didn’t update lock screen widgets. Fixed. - HydrationService.syncToAppStorage() — Same pattern. Fixed: added widget timeline reload.
Toggle Haptic Feedback (3 Settings Views)
- NotificationSettingsView — 8+ notification toggles had no tactile feedback. Fixed:
.sensoryFeedback(.selection, trigger:). - CoachSettingsView — “Proactive Interventions” toggle. Fixed.
- EncryptionSettingsView — “Enable Encryption” toggle. Fixed.
Files Changed (7)
Services/TaskRepository.swift
Services/ContactRepository.swift
ViewModels/WellnessViewModel.swift
Services/HydrationService.swift
Views/Settings/NotificationSettingsView.swift
Views/Settings/CoachSettingsView.swift
Views/Settings/EncryptionSettingsView.swift
Round 11 Audit — Race Conditions, Ghost Data & Haptic Polish
v1.1.14-agent parallel audit covering ghost data, error swallowing, animation/haptic gaps, pipeline reliability, and ViewModel race conditions.
Ghost Data Fix (1 Critical)
- TaskRepository.restoreTask() — User restores deleted task (undo), server call fails → no SyncEngine enqueue → restored task vanishes on next refresh. Fixed: added enqueue in catch block.
Race Condition Fixes (3 High)
- WellnessViewModel.completeHabit() — Between
completedHabitIds.contains()guard andtodayCompletions.append(), a second rapid tap could race through, causing duplicate XP awards. Fixed: atomiccompletingHabitIdsSet with.insert().insertedguard. - MedicationViewModel.takeMedication() — Same pattern — rapid taps could trigger double-dose logging. Fixed: atomic
takingMedicationIdsSet. - FocusViewModel.scheduleTimer() — Timer loop
while !Task.isCancelleddidn’t checkisActive, sostopTimer()could leave one extra tick. Fixed: addedself.isActiveguard.
Haptic Polish (4 Improvements)
- MainTabView —
.selectionhaptic on tab change. - PlanView —
.mediumhaptic on swipe-delete task. - JournalView —
.mediumhaptic on swipe-delete journal entry. - AIHubView —
.mediumhaptic on swipe-delete conversation.
Files Changed (8)
Services/TaskRepository.swift
ViewModels/WellnessViewModel.swift
ViewModels/MedicationViewModel.swift
ViewModels/FocusViewModel.swift
Views/MainTabView.swift
Views/Plan/PlanView.swift
Views/Wellness/JournalView.swift
Views/AIHub/AIHubView.swift
Round 10 Audit — Ghost Data, Animation Polish & UX Hardening
v1.1.1Comprehensive audit found 6 ghost data bugs (data saved locally but lost on server failure), plus 4 UX gaps including swipe-dismiss protection, widget staleness, empty state animation, and onboarding haptics.
Ghost Data Fixes (6 Critical)
- CalorieService.addEntry() — Entry saved locally, server insert fails → catch block had no SyncEngine enqueue → entry vanishes on next refresh. Fixed: restructured scoping + added enqueue.
- CalorieService.addWeightEntry() — Same pattern. Weight entry saved locally, server failure → lost. Fixed.
- TaskRepository.updateActualMinutes() — Local cache updated, server
update()had no try/catch → actual minutes revert on failure. Fixed: wrapped with SyncEngine fallback. - TaskRepository.updateEnergyCost() — Same pattern. Energy cost label reverts on server failure. Fixed.
- SharedGoalRepository.archiveGoal() — Server call with no catch → archive status lost on failure. Fixed: optimistic local update + catch with enqueue.
- SharedGoalRepository.deleteGoal() — Server delete with no catch → goal deletion lost on failure. Fixed: optimistic + enqueue.
UX Hardening
- AddTaskSheet — Added
.interactiveDismissDisabled(currentStep > 0)so users can’t accidentally lose 9 steps of task creation by swiping down mid-wizard. - TaskViewModel — Widget staleness eliminated: added
WidgetCenter.shared.reloadAllTimelines()after task create, complete, and delete. - PlanEmptyState — Scale + opacity + offset entrance animation (hero icon 0.6→1.0, text slides up). Respects
shouldReduceMotion(). - OnboardingView — Added
.lighthaptic to skip button.
Files Changed (8)
Services/CalorieService.swift
Services/TaskRepository.swift
Services/SharedGoalRepository.swift
ViewModels/TaskViewModel.swift
Views/Plan/AddTaskSheet.swift
Views/Plan/PlanView.swift
Views/Onboarding/OnboardingView.swift
Services/HydrationService.swift
Guest-to-Account Data Migration — SyncEngine Replay on Upgrade
v1.1.1When a guest user creates an account, all locally-queued data is now automatically migrated to the server. Previously, guest data was trapped in OfflineStore forever — creating an account started fresh.
How It Works
- Guest taps “Create Account” in Settings →
AppState.upgradeGuestToAccount()saves the guest UUID, clears guest mode, shows AuthView - User signs up →
.signedInfires → detectspendingGuestMigrationId OfflineStore.remapUserId(from:to:)rewrites all cached JSON files, replacing local guest UUID with new server UUID (handles encryption transparently)SyncEngine.remapUserId(from:to:)rewrites all queued payloads and dead-lettered changes- SyncEngine triggers immediate
syncPendingChanges()— all guest data uploads to Supabase under the new account
Key Design Decisions
- UUID replacement at raw JSON level — handles all 20+ entity types uniformly without per-type decode/re-encode
- Dead letter queue also remapped — no data left behind
- Settings shows “Create Account” card only when
isGuestModeis true; Delete Account hidden for guests
Files Changed (4)
App/AppState.swift
Services/SyncEngine.swift
Services/OfflineStore.swift
Views/Settings/SettingsView.swift
Fix Guest Mode — Fully Local-Only, Zero Server Calls
v1.1.1A user reported that “guest mode seems to not work.” Root cause: the entire guest flow depended on Supabase anonymous auth (requires network). Guest mode was 100% broken offline — 20+ call sites would fail. Redesigned to local-first architecture with zero server calls.
Redesigned Architecture
enterGuestMode()generates persistent local UUID, callsresolveUserId()so all ViewModels get the guest UUID instantly, setsappMode = .localrestoreGuestModeIfNeeded()restores guest mode on cold launch from UserDefaults, skipsobserveAuthChanges()entirelysignOut()updated: skips push token deactivation and Supabase sign-out for guests- Data flow: ViewModels call
awaitUserId()→ local UUID → repos try server → fail → OfflineStore fallback. No push, no realtime, no JWT refresh
Files Changed (4)
App/AppState.swift
ViewModels/AuthViewModel.swift
Views/Auth/AuthView.swift
App/ConvoActApp.swift
Onboarding & Animation Polish — Premium Feel for First-Run & Celebrations
v1.1.1Two major UX polish tracks: enhanced onboarding animations with staggered entrances, floating logo, and animated page indicators — plus a new confetti celebration system for level-ups and task completions.
Onboarding Enhancements
- Animated icon entrance per page: icons scale from 0.5 → 1.0 with bouncy spring + fade in
- Staggered title/subtitle entrance: slide up from 20pt offset with 0.15s/0.25s/0.3s delays
- Welcome page: app logo gets
.glowPulse()effect + gentle floating animation (±4pt, 3s cycle) - Animated page indicator: current page shows wider capsule (20pt) with spring transition
- Assessment cards: scale to 1.02x on selection; checkmark icons use
.contentTransition(.symbolEffect(.replace)) - All animations gated behind
shouldReduceMotion()for accessibility
Confetti Celebration System (New)
ConfettiCanvasViewusingTimelineView(.animation)+Canvasfor 60fps rendering- 50–80 particles with random shapes, colors, rotation, spin, drift — auto-clear after 2.5s
- Reduced motion fallback: brief opacity flash instead of particles
- Reusable
.confettiCannon(trigger:)ViewModifier
Level-Up & Task Completion Polish
- RewardBadge: confetti on level-up, card scale-in with bouncy spring, emoji pulse, streak haptic
- PlanView: checkmark bounces on completion, circle fill animates, haptic upgraded to Core Haptics pattern
- HabitTrackingView: checkbox icon bounces on completion
Files Changed (7)
Views/Components/ConfettiView.swift (new)
Views/Components/RewardBadge.swift
Views/Onboarding/OnboardingView.swift
Views/Plan/PlanView.swift
Views/Wellness/HabitTrackingView.swift
ConvoAct.xcodeproj/project.pbxproj
Resources/Localizable.xcstrings
March 21, 2026
iOSRound 9 Audit — 7 SyncEngine Replay Handlers Silently Dropping Queued Data
v1.1.1Biggest data-loss finding yet. While Rounds 4–8 ensured all write operations correctly enqueue to SyncEngine on failure, the SyncEngine replay dispatcher was silently dropping 7 action types via default: break. Changes were enqueued → persisted → but never actually replayed to the server.
Missing Replay Handlers Added
focus_session/update— Duration updates made offline were silently droppedconversation/update— Conversation metadata updates droppedmessage/soft_delete— Deleted messages never soft-deleted on server, would reappear on next synccontact/send_request— Contact requests sent offline were lost. Also fixed ContactRepository to include from/to/message in enqueue payload (was nil before)contact/accept_request— Accepted requests offline were lostcontact/reject_request— Rejected requests offline were lostcontact/update_tags— Tag updates offline were lost
Additional Fixes
- All
default:cases now log to Sentry instead of silently breaking — future unhandled actions caught immediately - MovementTrackingView.formattedSteps —
NumberFormatter()was created on every render. Cached asstatic let stepsFormatter(expensive init: locale, calendar, number system)
Files Changed (3)
Services/SyncEngine.swift
Services/ContactRepository.swift
Views/Wellness/MovementTrackingView.swift
Round 8 Audit — Message Ghost Data, Force Unwrap Crash & Refreshable Gaps
v1.1.1Exhaustive audit of all 50+ write methods across every repository. Found the last ghost data bug, a potential crash from force unwrap, and 2 more missing .refreshable views.
Ghost Data (G1)
- MessageRepository.createMessage() — When online and server insert failed, the error propagated without enqueuing to SyncEngine. Message was saved locally but would never sync. Fixed: wrapped server call in do/catch, enqueue encrypted payload on failure, return local copy so UI isn’t broken.
Crash Risk (C1)
- RewardBadge.swift — Force unwrap
rewardService.nextLevel!.titlein accessibility label, guarded only by a ternary!= nilcheck. If the value changed between check and access (e.g., concurrent state update), this would crash. Fixed: replaced withif letoptional binding.
UX Gaps (U1–U2)
- SleepRoutineView — Missing
.refreshable. Users couldn’t retry a failed load of sleep routines and alarms. Fixed: added.refreshable { await viewModel.loadAll(forceReload: true) }. - MovementTrackingView — Missing
.refreshable. Same gap for workout history. Fixed: added.refreshable { await movementVM.loadAll() }.
Files Changed (4)
Services/MessageRepository.swift
Views/Components/RewardBadge.swift
Views/Wellness/SleepRoutineView.swift
Views/Wellness/MovementTrackingView.swift
Round 7 Audit — Task Delete Ghost Data, Conversation List UX & AIHub Accessibility
v1.1.1Deep audit after 6 prior rounds. Found 1 ghost data bug, 2 UX gaps, and 2 accessibility gaps. The try? audit and error swallowing audit came back completely clean.
Ghost Data (G1)
- TaskRepository.deleteTask() — When online, if the server soft-delete call failed, the error propagated without enqueuing to SyncEngine. Task was deleted locally but not on server — would reappear on next refresh. Fixed: wrapped server call in do/catch, enqueue on failure + Sentry capture.
UX Gaps (U1–U2)
- ConversationListView — Missing
.refreshable. Users couldn’t retry a failed conversation load without navigating away. Fixed. - ConversationListView — Missing
.alert()wired toviewModel.errorMessage. Load failures were silently swallowed with no user feedback. Fixed.
Accessibility (A1–A2)
- AIHubView — “New Chat” button had
.accessibilityIdentifierfor testing but no.accessibilityLabelfor VoiceOver. Fixed: added.accessibilityLabel("New chat"). - AIHubView — “Chat History” button same issue. Fixed: added
.accessibilityLabel("Chat history").
Files Changed (3)
Services/TaskRepository.swift
Views/Messages/ConversationListView.swift
Views/AIHub/AIHubView.swift
Round 6 Audit — Ghost Data in Delete Operations, Hydration Refresh & Widget Refresh
v1.1.1Final sweep found 3 ghost data bugs in delete operations and 2 UX gaps. The codebase’s try? audit came back completely clean — no remaining data-mutating error swallowing.
Ghost Data (G1–G3)
- HydrationService.deleteEntry() — When online and server delete fails, entry was deleted locally but NOT enqueued to SyncEngine for retry. Entry would reappear on next server refresh. Fixed: added
SyncEngine.shared.enqueue(...)in the catch block. - CalorieService.deleteEntry() — Identical pattern. Calorie entries deleted locally could reappear after failed server delete. Fixed.
- CalorieService.deleteWeightEntry() — Same pattern for weight entries. Fixed.
UX Gaps (U1–U2)
- HydrationTrackingView — Missing
.refreshable. If initial load failed, user had no way to retry without switching tabs. Fixed: added.refreshable { await hydrationService.loadToday() }. - FocusViewModel.stopTimer() — After a focus session ended,
WidgetCenter.shared.reloadAllTimelines()was never called. Focus widget could show stale data until next automatic refresh. Fixed: added widget reload after session sync.
Files Changed (4)
Services/HydrationService.swift
Services/CalorieService.swift
Views/Wellness/HydrationTrackingView.swift
ViewModels/FocusViewModel.swift
Resolve All Sentry Errors — JWT Refresh, Error Noise Reduction & SIGTERM Fix
v1.1.1Investigated all recent Sentry errors and resolved every issue with code fixes or appropriate triage. Addressed HTTP 401 burst (801 events, 71 users), noisy timeout errors (3,488 events, 101 users), and system-level app hangs.
APPLE-IOS-4 — HTTP 401 on /rest/v1/tasks (801 events, 71 users)
- Root cause: When the app is suspended for hours, the Supabase SDK’s internal JWT refresh timer doesn’t fire. On resume, the stale token causes 401s on every API call until the SDK eventually refreshes.
- Fix: Added
SupabaseService.refreshSessionIfNeeded()that proactively refreshes the JWT on every foreground return (called fromConvoActApp’s.onChange(of: scenePhase)handler). Skips refresh if the token has >1 minute of validity remaining.
APPLE-IOS-C — evaluateOnLaunch errors (3,488 events, 101 users)
- Root cause: The 5-second timeout safety gate in
DailyAdaptiveService.evaluateOnLaunch()was capturing every timeout as a full Sentry error event. These timeouts are expected behavior (network not ready at app launch) and the code correctly falls back to cached data. - Fix: Downgraded
URLError(.timedOut)to.info-level breadcrumb; real failures still captured as errors.
APPLE-IOS-B/1W/1X — App Hangs (2000ms threshold)
- System-level hangs in SwiftUI type resolution, dylib loading, and Swift metadata. All single-occurrence, 1 user each.
- Fix: Moved
SentrySDK.start()off main thread to reduce main-thread pressure at launch. Marked resolved — will auto-reopen if they recur.
Files Changed (3)
Services/SupabaseService.swift
App/ConvoActApp.swift
Services/DailyAdaptiveService.swift
Round 5 Comprehensive Audit — Data Integrity, UX Reliability & 5-Star Polish
v1.1.1 (build 5)Full-spectrum audit covering data integrity, UX reliability, and polish gaps. Three parallel implementation tracks addressed 21 findings across 5 data integrity issues, 8 UX reliability issues, and 8 polish improvements.
Data Integrity (D1–D5)
- OfflineStore.swift — Fixed read-modify-write race in
softDeleteTask(),restoreTask(),purgeOldDeletedTasks()by operating ontasksCachedirectly instead of load→modify→save - SyncEngine.swift — Made dead-letter retry transactional: build re-enqueue list first, enqueue all, then clear dead letters (prevents data loss on partial failure)
- ContactRepository.swift — Added SyncEngine enqueue on server failure for
sendContactRequest(),acceptRequest(),rejectRequest() - WellnessViewModel.swift — Added
checkDayRollover()method comparing current day tolastLoadDay, forces reload when date changes - WellnessView.swift — Added
scenePhaseobserver to trigger day rollover on foreground return
UX Reliability (U1–U8)
- SleepRoutineView — Replaced inline error text with proper
.alert()modifier - MovementTrackingView — Added
.alert()formovementVM.errorMessage - FocusView — Added
.alert()forsharedGoalViewModel.errorMessage - MainTabView — Added throttled (5-minute cooldown) medication/habit/hydration refresh on
.activescenePhase viaDataRefreshBus - MedicationVM, CycleVM, WellnessVM — Added offline feedback: “Saved offline — will sync when connected”
5-Star Polish (P1–P8)
- AddTaskSheet — Added
.scrollDismissesKeyboard(.interactively)andminHeight: 56for Dynamic Type - HabitTrackingView — Added VoiceOver
.accessibilityAction(named:)for Complete, Edit, Delete - FocusReadinessDetailView — Added text labels (“Excellent”, “Good”, “Fair”, “Low”) next to color indicators per WCAG
- PlanView, ConversationListView — Changed
.lineLimit(1)to.lineLimit(2)on titles - AccessibilitySettingsView, SettingsView — Added
.sensoryFeedback(.selection, trigger:)to toggle helpers - MessageThreadView — Added
.refreshable { await loadMessages() }
Files Changed (19)
Services/OfflineStore.swift
Services/SyncEngine.swift
Services/ContactRepository.swift
ViewModels/WellnessViewModel.swift
ViewModels/MedicationViewModel.swift
ViewModels/CycleViewModel.swift
Views/Wellness/WellnessView.swift
Views/Wellness/SleepRoutineView.swift
Views/Wellness/MovementTrackingView.swift
Views/Wellness/HabitTrackingView.swift
Views/Focus/FocusView.swift
Views/Focus/FocusReadinessDetailView.swift
Views/MainTabView.swift
Views/Plan/AddTaskSheet.swift
Views/Plan/PlanView.swift
Views/Messages/ConversationListView.swift
Views/Messages/MessageThreadView.swift
Views/Settings/AccessibilitySettingsView.swift
Views/Settings/SettingsView.swift
Add Changelog Section to README
Added a Changelog table to README.md that logs every push with date, time, and a short summary. Also added a Table of Contents link to the new section.
Eliminate Ghost Data & Error Swallowing Across All Sync Paths
Comprehensive audit and fix of ghost data (local optimistic writes that silently fail to sync) and error swallowing (try? patterns that discard sync failures without logging). Two-round sweep identified 29 code locations across 12 ViewModels and 6 repositories, plus 7 additional issues found in a re-sweep.
Repository Layer — SyncEngine Fallback on Server Failure
- HydrationService.addEntry() — Online server insert failure now enqueues to SyncEngine for retry (was throwing without fallback, creating ghost hydration entries)
- SharedGoalRepository.createGoal() — Multi-step server operation now catches failures at any step and enqueues the full payload for deferred sync
- SharedGoalRepository.updateProgress() — Online failure now enqueues progress update for retry
- MessageRepository.deleteMessage() — Online soft-delete failure now falls back to local soft-delete + SyncEngine enqueue
- ContactRepository.updateTags() — Both offline and online-failure paths now enqueue for retry
Repository Layer — Encoding Error Capture
- SleepLogRepository
createLog()/updateLog()—try?encoding replaced withdo/catch+SentryErrorTracker.captureEncodingError() - SleepRoutineRepository
createRoutine()/updateRoutine()— Same fix - WorkoutLogRepository
createLog()— Same fix
ViewModel Layer — try? → do/catch + Sentry (18 methods)
- TaskViewModel —
createTask,createTasksBatch,updateTask,toggleComplete,restoreDeletedTask - MedicationViewModel —
addMedication,updateMedication - WellnessViewModel —
logMood,createHabit,completeHabit,incrementStreak,updateHabit - CycleViewModel —
logToday(update + create paths),updateSettings - SleepRoutineViewModel —
addRoutine,updateRoutine,logSleep - MovementViewModel —
logWorkout - ChatViewModel —
startNewConversation - MessagingViewModel —
createDirectConversation - FocusViewModel —
endSession,createSession - SharedGoalViewModel —
createGoal
Destructive Ops with User Feedback on Failure (5 methods)
- WellnessViewModel.deactivateHabit() — Added
do/catch+ Sentry +errorMessage - SleepRoutineViewModel.removeRoutine() — Same
- SleepRoutineViewModel.deleteSleepLog() — Same
- MovementViewModel.deleteWorkout() — Same
- SharedGoalViewModel.archiveGoal() — Added
errorMessage
Views
- SettingsView.deleteAccount() — Bulk
try?per-table deletion replaced with individualdo/catchper table, each logging to Sentry with table name (prevents silent partial account deletion / PII retention)
Bump Version to 1.1.1 (Build 5) for App Store Resubmission
v1.1.1 (build 5)Updated MARKETING_VERSION to 1.1.1 and CURRENT_PROJECT_VERSION to 5 across all targets in project.pbxproj for App Store resubmission after the iPad blank screen fix and data reliability improvements.
Update Credit Line App-Wide
Replaced the developer credit text across SettingsView and related files with the consistent tagline “Brought to life with love by Honorius Neogy”.
Improve Data Reliability — Fix Sync Data Loss, Add Delete Account, Harden Auth/Cache
Round 2 and Round 3 of the data reliability audit. Fixed 26 issues across subscription flow, habit tracking, notification scheduling, task management, messaging, medication, focus sessions, and encryption.
Subscription (Round 2)
- Purchase button now uses
selectedPlan.productIdinstead of hardcoded monthly ID - Restore purchases shows success/failure feedback
.unverifiedpurchases logged to Sentry
Habit & Wellness (Round 2)
- Added
completedHabitIdsdouble-tap guard - Added
lastLoadDayfor midnight boundary staleness detection - Atomic habit reminder rescheduling (schedule new first, then remove stale)
Task Management (Round 3)
TaskRepository.updateTask()— Changed from online-only enqueue to always-enqueue pattern- Added
togglingIdsSet to prevent rapid double-tap flip-flopping - SyncEngine now has
hasPendingChanges(for:); background refresh skipped when local changes pending
Focus Sessions (Round 3)
- Added
guard !isActiveto prevent duplicate sessions - Only counts completed sessions (not abandoned) for stats
- Added
cumulativeWorkSecondsfor accurate Pomodoro duration - Fixed Live Activity race condition:
currentActivity = nilbefore async end Task
Medication (Round 3)
- Added
takenTodayIdsdouble-dose guard - Background sync changed from
try?todo/catchwith error feedback
Messaging (Round 3)
- Full unread tracking via UserDefaults
lastSeenKeytimestamps - Wired
markConversationReadon thread open - Realtime messages inserted in chronological order;
isSendingset before awaits
Auth & Encryption (Round 3)
AppState.signOut()now callsEncryptionService.shared.deleteKey()to prevent cross-user key leakage- Encryption toggle now shows confirmation alert with migration warning
Add SKStoreReviewController, Fix All Test Concurrency Warnings, Bump Build to 4
Added App Store review prompts via a new ReviewPromptService singleton that tracks milestones and prompts intelligently. Fixed Swift 6 concurrency warnings in test targets by converting synchronous setUp/tearDown to async with MainActor.run {}.
SKStoreReviewController Integration
- New
ReviewPromptService.swift—@MainActorsingleton tracking milestones - Prompt conditions: 5+ focus sessions OR 10+ tasks OR 7-day streak, 14+ days since install, 90+ days since last prompt, new app version
- Trigger points:
RewardService.award()(level-up),FocusViewModel(session dismiss),WellnessViewModel(streak milestones at 7, 30, 100 days)
Test Concurrency Fixes
- BurnoutDetectorTests.swift — Converted to
override func setUp() async throwswithMainActor.run {} - ChatViewModelTests.swift — Same pattern for mock init/teardown
- FocusViewModelTests.swift — Same pattern for mock init/teardown
March 20, 2026
iOSFix Concurrency Warning in AnalyticsServiceTests
Converted synchronous setUp()/tearDown() to async with MainActor.run {} blocks in AnalyticsServiceTests to eliminate Swift 6 @MainActor isolation warnings. Established the pattern later applied to 3 more test files.
Defer Blocking Init Work to Prevent SIGTERM from Sentry Hang Tracker
Moved expensive initialization work (Sentry hang detection, cache invalidations) out of ConvoActApp.init() into deferred Task blocks. The Sentry hang tracker was detecting the synchronous init as a hang and sending SIGTERM, killing the app on launch.
Fix Blank Screen on iPad — Remove Opacity-0 Startup Animations
App Store FixFixed App Store rejection for blank screen on iPad. The root cause was opacity-0 startup animations that never completed on iPad due to timing differences. Removed the animations entirely and replaced with immediate content display.
Fix Concurrency Warning — Make hangDetectedKey Nonisolated
Added nonisolated keyword to a @MainActor class static let used as a default parameter, following Swift 6 strict concurrency patterns.
Add Advanced Feedback Diagnostics — Screen Recording, Analytics Dashboard, Hang Detection
Major enhancement to the feedback and diagnostics system. Added screen recording capture for bug reports, an internal analytics dashboard for metrics, hang detection reporting, and automatic log file attachments to Sentry bug reports.
Enhance All 3 Feedback Channels with Richer Diagnostics and UX
Improved the email, Sentry, and GitHub Issues feedback channels with richer diagnostic information, better UX flows, and more detailed device/app state collection.
Add User Feedback System — Email, Sentry Bug Reports & GitHub Issues
Added three feedback channels for users: pre-populated email with device info, in-app bug report form via Sentry user feedback events, and direct link to the GitHub issue tracker.
Add Website, App Store & Developer Links to README
Added badge links to the App Store listing, convoact.com website, and developer profile at the top of the README.
Add Comprehensive README with Full App Documentation
Created a detailed README covering all major features, architecture, screens, Apple Intelligence integration, Siri/App Intents, HealthKit integration, Live Activities, widgets, backend infrastructure, accessibility, security, project structure, and tech stack.
v1.1.0 — Production-Ready Release
v1.1.0Massive release encompassing the full migration from ObservableObject to @Observable, Swift 6 strict concurrency compliance, and App Store review fixes. The culmination of weeks of work preparing v1.1.0 for production. This is the version currently available for download.
Major Changes
- Full
@Observablemigration across all ViewModels - Swift 6 strict concurrency: eliminated all
@Sendablewarnings, added proper actor isolation - Deep link system rewritten from NotificationCenter to
@ObservableDeepLinkRouter - Sign-out cleanup migrated from NotificationCenter to
AppState.signOutCounter - Data refresh migrated to
@ObservableDataRefreshBus - All 33 HealthKit queries migrated from legacy callbacks to modern
HKSampleQueryDescriptor - Added 4 Live Activities (focus timer, medication, deadline, wake-up alarm)
- Added Apple Intelligence on-device AI via Foundation Models (~20 methods)
- Added 10 App Shortcuts + Siri integration
- Added Core Spotlight indexing
- Added end-to-end encryption (AES-256-GCM)
- Added offline-first architecture with SyncEngine
- 1,018+ accessibility annotations across 82+ files
February 24, 2026
iOSFix Sign in with Apple — Use Programmatic ASAuthorizationController
App Store FixReplaced the native SignInWithAppleButton (which had styling/callback issues) with a fully programmatic ASAuthorizationController implementation with a custom accessible button. Fixed authentication failures during App Store review.
Fix App Store Review Issues (Guidelines 2.1 & 5.1.1)
App Store FixAddressed App Store rejection for guideline 2.1 (app completeness — crash on launch) and 5.1.1 (data collection — privacy manifest). Fixed launch crash, added PrivacyInfo.xcprivacy, and ensured all required privacy declarations were present.
February 6, 2026
iOSInitial Commit
v1.0.0Initial codebase commit with the core ConvoAct app structure: SwiftUI views, MVVM architecture, Supabase backend integration, HealthKit, task management, focus timer, wellness tracking, AI coach, and messaging.
No entries match your filters
Try adjusting your search or category filters.Codebase at a Glance
The numbers behind ConvoAct's engineering.