Open product/engineering decisions, with a recommendation for each. Mark Accepted or Override before/during the relevant phase.
Context: Apple Watch with HKWorkoutSession + HKLiveWorkoutBuilder does GPS smoothing, distance integration, pace, splits, HR sampling, and auto-pause. We can either consume Apple's authoritative metrics or write all of that ourselves.
Decision: Watch-primary, day 1. No phone-only mode in V1. Phone subscribes to live metrics over WatchConnectivity and runs the AI/audio layer.
Consequences:
- Phone has zero CoreLocation code, zero distance/pace algorithms.
- watchOS target ships in Phase 0.
- Founder must wear the watch on every run.
- The Phase 4 "add Watch" workstream is gone; new Phase 4 is polish + App Store.
Options: Anthropic Claude / OpenAI / Apple Intelligence on-device / Hybrid.
Recommendation: Anthropic — Sonnet 4.6 for generation, Haiku 4.5 for chat reply. Strong personality conditioning; mature prompt caching.
Consequence: API key on the proxy only.
One TypeScript file. Free tier. Edge latency. Easy to add App Attest later. DNS for aarun.club is on Cloudflare nameservers; the Worker is bound to the api.aarun.club custom domain.
Consequence: Second tiny repo aarc-proxy. Phase 0 ships hello-world at api.aarun.club/ping; Phase 1 wires up /generate-script. App config hard-codes the hostname so we never depend on a *.workers.dev URL.
Recommendation: No auth in Phase 1 (founder-only TestFlight). Apple App Attest before any wider distribution (Phase 4).
Apple's installed voices (Premium/Enhanced when available). ElevenLabs and Personal Voice are Phase 4 polish.
Consequence: Personality tone is conveyed through wording and cadence in V1. Acceptable.
Note: With watch-primary tracking, our local DB shrinks dramatically — only companion data, not workout truth. SwiftData is more than adequate.
Buys SwiftData + Observation framework + WorkoutKit niceties. Founder is on a current iPhone and Apple Watch.
AVAudioSession .playback / .spokenAudio / [.mixWithOthers, .duckOthers]. Confirmed compatible with Apple Music, Spotify, Podcasts, Audible.
MapKit. Reads HKWorkoutRoute from HealthKit and overlays.
Voicemail / async, per the brief. No real-time voice chat in V1.
Manifest (name, description, exposed settings) bundled in the app for offline UI. The actual system prompt lives on the proxy and can be tuned without an app update.
HKWorkoutConfiguration(activityType: .running, locationType: .indoor). Apple computes distance from wrist accelerometry — usually within ~3% on modern Apple Watches. Still expose a "correct distance" button on the post-run summary that updates the workout via HealthKit.
This is much simpler than the original "phone-side CMPedometer" plan.
No paywall through Phase 4. Premium voices (ElevenLabs / Personal Voice) are the obvious paid tier when it's time.
Manual TestFlight feedback for now. Add Sentry only when we have more than one user.
Ship as AARC with subtitle like "AI Running Companion". Keep the working expansion in marketing and personality prompts where appropriate. Avoid medical/health claims.
iOS 17 Personal Voice lets the founder record their own voice. Excellent demo value, zero ongoing cost. Schedule for Phase 4.
Watch stamps the finished workout with metadata: ["aarcRunId": runId.uuidString] before finishWorkout. Phone reads this to associate Health workouts with our companion records.
Consequence: Lossless link even if our local DB is wiped — we can reconstruct the run-companion mapping by enumerating Health workouts.
We do not store split rows in our DB. We derive them per-render by querying HKStatisticsCollectionQuery over the workout's interval. Cheap, always consistent with Apple Fitness.
Context: The founder's only iPhone is also their daily driver and contains years of real training data in Apple Health. Every Phase 1+ run we record will write to HealthKit. Without a safety mechanism, AARC test/dev runs would mix indistinguishably with real runs and pollute training history.
Decision: Two-layer safety, both default-ON:
- Tag mode (default ON). Every HK workout AARC writes carries metadata
aarc.test_data: true. A "Wipe AARC test data" action queries HealthKit by that metadata key and bulk-deletes matching workouts (HK cascades to associated samples and route). - Skip mode (default OFF, opt-in). A second toggle that prevents any HK writes whatsoever — runs live only in AARC's local SwiftData store. For moments of paranoia or buggy builds.
UI affordances make test mode unmissable:
- Banner on active run and post-run summary while either mode is on
- "TEST" badge on history rows
- Settings panel showing test-workout count + wipe button + last-wipe timestamp
Toggling off: When the founder flips "Tag as test data" OFF, future runs are written without the tag and become permanent in Health. A confirmation alert prevents accidental flips. Wipe button continues to operate strictly on aarc.test_data == true workouts, so real runs are never in scope.
Other metadata we always stamp (regardless of test mode): aarc.run_id, aarc.created_at, aarc.app_version. Useful for support/debugging and for linking HK workouts back to our companion data in SwiftData.
Status: accepted (mandatory before any HK write lands).
Domain: aarun.club (registered, DNS to be moved to Cloudflare in Phase 0).
| Hostname | Purpose | Phase |
|---|---|---|
api.aarun.club |
Cloudflare Worker proxy: /ping, /generate-script, /chat-reply, /post-run-summary, /tts |
0+ |
app.aarun.club |
Universal Links + Associated Domains. Hosts apple-app-site-association. Used for deep links (/race/:id, share links from Phase 3) |
0 (reserve), 3+ (use) |
aarun.club / www.aarun.club |
Marketing / landing site | Post-launch (Phase 4 if time, else later) |
Consequences:
- App ships pointing at
https://api.aarun.clubfrom build 1. Never a*.workers.devURL in shipped bundles. - Universal Links need
app.aarun.club/.well-known/apple-app-site-associationpublished before any link-based feature ships (Phase 3 race-share, etc.). - Privacy policy (required for App Store) lives at
aarun.club/privacy. Stand up a one-pager before App Store submission in Phase 4. - Bundle ID
club.aarun.AARCis consistent with the domain.