HealthProbe / AGENTS.md
1 contributor
218 lines | 7.497kb

HealthProbe – Multi-Model Development Guide

Overview

HealthProbe is built by multiple AI models, each owning a distinct domain.
This document defines boundaries, interfaces, and handoff contracts.


Model Allocation

Domain Owner Tools
UI / SwiftUI Views Claude Code Xcode, SwiftUI, CLAUDE.md
Data Models (SwiftData) Dedicated model session Xcode, Swift
HealthKit Integration Dedicated model session Xcode, HealthKit docs
Anomaly Detection Algorithms Dedicated model session Swift, statistical references
Sync Monitoring Dedicated model session Xcode, CloudKit docs
Documentation Claude Code + dedicated session Markdown
Tests Dedicated model session XCTest, Swift Testing

Directory Ownership

HealthProbe/
├── Views/           ← Claude Code (UI)
├── ViewModels/      ← Claude Code (UI)
├── Utilities/       ← Claude Code (shared helpers, mocks)
├── Models/          ← Models agent (SwiftData schemas)
├── Services/        ← Services agent (HealthKit, anomaly, sync)
└── Tests/           ← Tests agent

Rule: Each agent writes only within its owned directories.
Cross-boundary changes require an explicit interface contract (protocol) first.


Interface Contracts

All service boundaries are defined as Swift protocols.
Claude Code (UI) consumes protocols — never concrete implementations.

HealthMonitorProtocol

/// Owned by: Services agent
/// Consumed by: UI (DashboardViewModel)
protocol HealthMonitorProtocol {
    var currentStatus: HealthStatus { get }
    var lastChecked: Date? { get }
    func runCheck() async throws
}

AnomalyStoreProtocol

/// Owned by: Services agent
/// Consumed by: UI (AnomalyListViewModel)
protocol AnomalyStoreProtocol {
    var anomalies: [DetectedAnomaly] { get }
    func markResolved(_ anomaly: DetectedAnomaly) async throws
}

AuditTrailProtocol

/// Owned by: Services agent
/// Consumed by: UI (AuditTrailView)
protocol AuditTrailProtocol {
    var entries: [AuditTrailEntry] { get }
    func export() async throws -> Data  // JSON
}

SyncMonitorProtocol

/// Owned by: Services agent
/// Consumed by: UI (SyncViewModel)
protocol SyncMonitorProtocol {
    var iCloudEnabled: Bool { get }
    var lastSyncDate: Date? { get }
    var stateChanges: [SyncStateChange] { get }
}

Shared Types (Models Agent)

These types are defined once in Models/ and shared across all agents:

// Models/TypeDistributionBin.swift
@Model
final class TypeDistributionBin {
    var bucketStart: Date
    var bucketEnd: Date
    var count: Int
}

// Models/TypeCount.swift
// TypeCount owns zero or more TypeDistributionBin records.
// These bins store sample counts and import anchors, not raw health values.

// Interface updated 2026-05-12 — see AGENTS.md
// Models/HealthRecord.swift
// HealthRecord stores one anonymized HealthKit record fingerprint plus its start/end dates.
// It intentionally does not store raw health values, device identifiers, or source metadata.
// UI may compare HealthRecord fingerprints between adjacent snapshots to expose losses
// that are masked by newly-added records with the same total count.
// High-volume snapshots store these records in TypeCount.recordArchiveData instead of
// creating one SwiftData model per record, avoiding main-thread stalls after import.

// Interface updated 2026-05-13 — see AGENTS.md
// TypeDistributionBin also stores content hashes and HealthKit query anchors.
// Import uses a global anchored query per data type so follow-up snapshots fetch only
// HealthKit deltas instead of scanning calendar blocks with fixed per-query latency.

// Models/DetectedAnomaly.swift
enum AnomalyType: String, Codable {
    case historicalInsertion = "historical_insertion"
    case silentDeletion      = "silent_deletion"
    case duplicate           = "duplicate"
    case divergence          = "divergence"
}

enum Severity: String, Codable, Comparable {
    case info, warning, critical
}

enum HealthStatus: String {
    case healthy, warning, critical, unknown
}

Any model changes must be announced in this file before other agents consume them.


Handoff Process

When a module is ready to be consumed by another agent:

  1. Define the protocol in Services/Protocols/ (services agent)
  2. Implement a mock in Utilities/Mocks.swift (Claude Code)
  3. Build UI against the mock (Claude Code)
  4. Replace mock with real implementation (services agent)
  5. Integration test (tests agent)

This allows UI development and service development to proceed in parallel.


Algorithms & Detection Logic

The following modules involve non-trivial logic and should be reviewed carefully:

Module File Description
Anomaly Detector Services/AnomalyDetector.swift Statistical detection: insertions, deletions, duplicates, divergence
Divergence Engine Services/DivergenceEngine.swift Time-series trend analysis, σ comparison
Fingerprinter Services/SampleFingerprinter.swift Duplicate detection via sample hashing
Snapshot Comparator Services/SnapshotComparator.swift Diff between two HealthKit snapshots
Distribution Comparator Services/SnapshotDiffService.swift Daily per-type distribution diff to reveal old-data disappearance masked by new data

Guidelines for algorithm modules: - Document assumptions explicitly (e.g., "assumes continuous monitoring since install") - All thresholds (e.g., age > 7 days) must be configurable constants, not magic numbers - Include unit tests for edge cases (empty snapshots, partial data, clock skew) - No UI code; return plain Swift types only


Privacy Directives — All Agents

Mandatory across all modules: - No credentials, API keys, tokens, or certificates in any file - No personal data: names, emails, phone numbers, dates of birth - No device identifiers: UDID, serial number, advertising ID, device name - No account identifiers: Apple ID, iCloud account info, CloudKit record IDs - No raw health values in code, tests, previews, logs, or comments - No location data or patterns enabling re-identification - Synthetic data only in tests and previews


Communication Between Agents

When one agent needs to communicate a decision or change to another:

  1. Update this file (AGENTS.md) with the protocol/interface change
  2. Update the relevant protocol in Services/Protocols/
  3. Add a comment in the affected file: // Interface updated YYYY-MM-DD — see AGENTS.md

Current Status

Module Status Owner
SwiftData Models ✅ Done Models agent
HealthKit Integration ✅ Done Services agent
Snapshot Diff Service ✅ Done Services agent
Service Protocols ⏳ Not started Services agent
Anomaly Detection ⏳ Not started Services agent
Sync Monitor ⏳ Not started Services agent
UI – App entry + TabView ✅ Done Claude Code
UI – Dashboard ✅ Done (functional, minimal) Claude Code
UI – Snapshots + Detail ✅ Done Claude Code
UI – Data Types ✅ Done Claude Code
UI – Settings ✅ Done Claude Code
Unit Tests ⏳ Not started Tests agent