HealthProbe / CLAUDE.md
1 contributor
239 lines | 7.286kb

HealthProbe – Claude Code Instructions

Project Context

HealthProbe is an iOS app that audits Apple HealthKit data integrity.
It detects anomalies: data loss, historical insertions, duplicates, divergence trends.
Full specification: HealthProbe/Doc/HealthProbe – Complete Specification & Motivations.md

Current state: SwiftUI + SwiftData app is active. Product direction changed on 2026-05-18: HealthProbe is a local audit/capture agent. Do not add HealthProbe CloudKit/iCloud sync.


Claude Code Scope: UI Layer

Claude Code is responsible for: - All SwiftUI Views (Views/ directory) - All ViewModels (ViewModels/ directory) - Navigation structure and tab/split layout - Design system (colors, typography, spacing) - Preview providers for all views - Accessibility (VoiceOver, Dynamic Type)

Claude Code does NOT own: - Services/ — HealthKit queries, anomaly detection, archive store, context monitoring (see AGENTS.md) - Models/ — SwiftData models (see AGENTS.md) - Entitlements, Info.plist, project configuration

When services are not yet implemented, consume their protocols and use mock implementations for UI development.


Target Screen Structure

App (TabView)
├── Tab 1: Dashboard          → DashboardView
├── Tab 2: Anomalies          → AnomalyListView → AnomalyDetailView
├── Tab 3: Audit Trail        → AuditTrailView
├── Tab 4: Archive Status     → ArchiveStatusView
└── Tab 5: Settings           → SettingsView

DashboardView

  • Large status indicator: ✅ Healthy / ⚠️ Check / 🚨 Critical
  • Last check timestamp
  • Summary cards: samples tracked, anomalies found (all-time)
  • Up to 3 recent active alerts (tappable → AnomalyDetailView)
  • "Check Now" button (calls monitoring service)

AnomalyListView

  • List of DetectedAnomaly sorted by date (most recent first)
  • Filter: All / Critical / Warning / Info
  • Filter: by type (deletion, insertion, duplicate, divergence)
  • Each row: severity badge, type, sample type, date
  • Swipe to mark resolved

AnomalyDetailView

  • Full anomaly details
  • Evidence dictionary displayed as key-value rows
  • Severity badge
  • Share button → exports as Markdown (for bug reports)
  • "Mark Resolved" action

AuditTrailView

  • Chronological list of AuditTrailEntry
  • Each row: timestamp, event type chip, message
  • Search/filter by event type
  • Export button → JSON

ArchiveStatusView

  • Current local archive health
  • Last archive verification timestamp
  • Selected data types covered by forensic capture
  • Recent Health/iCloud context events (for correlation only; no HealthProbe sync)

SettingsView

  • Check frequency: 2h / 6h / 12h / 24h (Picker)
  • Sample types to monitor (MultiSelect toggle list)
  • Alert thresholds (severity level for push notifications)
  • Point export/report actions for selected findings
  • Delete all audit data (destructive, confirm alert)

Design Guidelines

Tone: Professional, calm, medical-adjacent. Not alarming unless critical.

Color System: swift // Status colors .healthyGreen // SF: green — all clear .warningAmber // SF: yellow — attention needed .criticalRed // SF: red — action required .neutralGray // SF: gray — informational / resolved

Typography: SF Pro (system font). No custom fonts.

Spacing: 8pt grid. Use VStack(spacing: 12) as baseline.

Icons: SF Symbols only. No third-party icon sets.

Key SF Symbols: - checkmark.shield.fill — healthy status - exclamationmark.triangle.fill — warning - xmark.shield.fill — critical - clock.arrow.circlepath — audit trail - externaldrive.fill.badge.checkmark — archive status - waveform.path.ecg — health data - doc.text.magnifyingglass — anomaly detail

Dark mode: Required. Test in both modes.

Privacy-first UI: - Health metric values are never shown in plain text in list rows - Values visible only in AnomalyDetailView after tap - Evidence dictionary values shown as monospace text, not highlighted


SwiftData Integration

Models are defined in Models/. Reference them read-only from views:

// In views, use @Query — never write directly from a View
@Query(sort: \DetectedAnomaly.detectedAt, order: .reverse)
private var anomalies: [DetectedAnomaly]

// Mutations go through ViewModels or services only

Until Models/ are implemented, use mock data via PreviewProvider.


ViewModel Pattern

// Pattern for all ViewModels
@MainActor
@Observable
final class DashboardViewModel {
    private let monitor: HealthMonitorProtocol  // protocol, not concrete type
    
    var status: HealthStatus = .unknown
    var recentAnomalies: [DetectedAnomaly] = []
    var lastChecked: Date?
    
    init(monitor: HealthMonitorProtocol = HealthMonitorService.shared) {
        self.monitor = monitor
    }
    
    func refresh() async {
        await monitor.runCheck()
    }
}

Always inject dependencies via protocols — makes previews and tests possible without real HealthKit.


Mock Data Protocol

Until services are ready, define preview mocks in Utilities/Mocks.swift:

struct MockHealthMonitor: HealthMonitorProtocol {
    func runCheck() async { }
    var status: HealthStatus { .warning }
}

extension DetectedAnomaly {
    static var preview: DetectedAnomaly {
        DetectedAnomaly(
            detectedAt: .now,
            type: "silent_deletion",
            severity: "warning",
            sampleType: "Steps",
            summary: "72 samples missing without deletion event",
            evidence: ["loss_count": "72", "loss_percent": "23.4"]
        )
    }
}

File Organization

HealthProbe/
├── Views/
│   ├── Dashboard/
│   │   ├── DashboardView.swift
│   │   └── StatusCardView.swift
│   ├── Anomalies/
│   │   ├── AnomalyListView.swift
│   │   └── AnomalyDetailView.swift
│   ├── AuditTrail/
│   │   └── AuditTrailView.swift
│   ├── Archive/
│   │   └── ArchiveStatusView.swift
│   └── Settings/
│       └── SettingsView.swift
├── ViewModels/
│   ├── DashboardViewModel.swift
│   ├── AnomalyListViewModel.swift
│   └── ArchiveStatusViewModel.swift
├── Models/           ← NOT owned by Claude Code
├── Services/         ← NOT owned by Claude Code
└── Utilities/
    ├── Mocks.swift
    ├── DateFormatters.swift
    └── DesignSystem.swift

Privacy Directives

Mandatory — no exceptions: - No credentials, tokens, or API keys in any file - No personal data, device identifiers, or account identifiers - No real health values in code, comments, previews, or tests - Synthetic preview data only (see Mocks.swift above)


Before Marking a Task Complete

  • [ ] View renders in both Light and Dark mode (use Preview)
  • [ ] VoiceOver labels set on interactive elements
  • [ ] Dynamic Type tested (at least xSmall and AX3)
  • [ ] Works with mock data (no real HealthKit dependency in View layer)
  • [ ] No health values displayed without explicit user tap
  • [ ] Compiles without warnings