Building My Health OS
Last Tuesday, my Telegram buzzed at 7am: “Your resting heart rate is 9 bpm above your 30-day average. I’ve converted today’s swim to a rest day.” That was Zeus — my AI assistant — reading my biometrics before I’d even got out of bed. By Wednesday I had a sore throat. By Thursday I was glad I’d listened.
I didn’t buy that capability. I built it. On a Mac Mini, using Claude Code, without being an engineer.
Why
I train for triathlons and I track everything. Apple Ultra Watch for sleep, heart rate, and workouts. 8Sleep mattress for HRV overnight. Arboleaf scale for weight. Strava for swim and run tracking. Peloton for cycling. The data was all there — in six apps that never spoke to each other. Every morning I’d check each one trying to answer a simple question: should I push hard today or back off?
I got tired of being my own data analyst. So I built a system to do it for me.
The stack

Everything runs on a Mac Mini sitting in my house. No cloud, no subscriptions, no one else’s algorithm deciding what’s relevant. Here’s how each data source connects:
Apple Ultra Watch is the hub. It records sleep stages, heart rate, HRV, resting heart rate, VO2 max, step count, active calories, and every workout — swim, bike, run — with sport-specific metrics (swim stroke rate, run cadence, cycling power). All of it flows into Apple Health on my iPhone automatically.
Health Auto Export — an iOS app — bridges the iPhone to the Mac Mini. It runs two parallel sync paths. The first is a REST API push every 60 minutes: the app POSTs workout and metric JSON payloads directly to Health OS endpoints (/api/push/workouts and /api/push/metrics) on the Mac Mini’s local IP. The second is an iCloud file sync: the app writes .hae files (lzfse-compressed JSON) to iCloud Drive, which propagates to the Mac. A cron job on the Mac runs three times daily (6am, 2pm, 10pm), decompressing the .hae files into plain JSON using Apple’s lzfse codec and dropping them into a shared data directory.
Two paths sounds redundant, but the API push can fail if my phone’s on cellular or the Mac Mini’s local IP changes. The iCloud sync can lag by hours. Having both means data usually arrives within an hour and always arrives within eight.
8Sleep connects directly from the Mac Mini via their OAuth2 API. Health OS authenticates with the 8Sleep auth endpoint, stores a session token, and pulls 14 days of sleep data on each ingestion cycle — HRV, respiratory rate, skin temperature, sleep stage durations, toss-and-turn count. The 8Sleep data is particularly valuable because the mattress sensors capture HRV passively all night, unlike the Apple Watch which samples intermittently.
Arboleaf scale syncs weight to Apple Health over Bluetooth when I step on it each morning. From there it follows the same iPhone → Health Auto Export → Mac Mini pipeline as everything else. Health OS computes a 7-day rolling average and trend direction.
Strava and Peloton workouts reach Health OS indirectly — both sync to Apple Health, which means Health Auto Export captures them. I don’t need separate API integrations for either.
The backend is Node.js with SQLite (WAL mode for concurrent reads during ingestion). The frontend is vanilla JavaScript — no React, no build toolchain. Data ingests every 10 minutes from the shared directory, and the dashboard serves on the local network. OpenClaw (Zeus) runs as a separate service on the same machine, watching for health alerts and handling Telegram communication.
One number every morning
Health OS boils everything down to a readiness score — 0 to 100. Green: go hard. Yellow: moderate. Red: rest.
It’s weighted: sleep quality (30%), HRV (20%), training load (25%), resting heart rate trend (15%), recovery patterns (10%). Those weights come from what I’ve observed about my own body, not what Whoop or Oura decided should be default.
On red days, the system overrides my training plan. No willpower needed on the days I have the least of it.
Zeus
Zeus is the part that changed my behaviour. He’s an AI assistant powered by OpenClaw, running on the same Mac Mini, connected to me via Telegram. He does three things:
Alerts. When Health OS detects something — elevated resting heart rate, overreaching, a missed session — Zeus messages me directly. I don’t check the dashboard for bad news. Bad news finds me.
Meal logging. I photograph what I eat and send it to Zeus. Claude’s vision identifies the food, estimates macros, and logs it into Health OS. Zeus replies with the breakdown and tells me how much protein and calories I have left for the day. Three seconds, no searching databases, no weighing portions. That’s why I’ve stuck with food tracking for the first time.

Briefings. I can ask Zeus how I’m doing and he pulls today’s readiness, planned session, last night’s sleep, and nutrition summary in one message.
The triathlon engine

I’m training for a sprint triathlon — 800m swim, 60km bike, 10km run — on a nine-week structured plan. Health OS manages every session. It flags when I’m over-cycling and under-swimming (guilty), tracks how my run pace degrades after a bike session (critical for race-day pacing), and predicts my finish time weekly based on real training data.
Built with Claude Code
I’m not a developer. I learned to code in 2019 — enough to understand the medium, not to ship production software alone. Health OS was built entirely with Claude Code. Backend, frontend, database, alerts, gamification — all of it.
This isn’t vibe coding. I made deliberate choices: SQLite because I don’t need a server database for a personal tool. Vanilla JS because I want to read my own code without a build toolchain. Separated ingestion from the API so I can debug each independently. The AI wrote the code. The architectural thinking was mine.
What’s changed is who gets to ship. The gap between having good technical judgment and being able to act on it used to require hiring someone. That’s no longer true for a growing category of problems.
What breaks
Claude can’t weigh your chicken through a camera. The macro estimates are directional, not precise. Good enough for “I need more protein today,” not for competitive nutrition planning.
And I’ve caught myself checking the readiness score before checking how I actually feel. Data is a tool, not an oracle.
What’s next
Bloodwork and hormone analysis. The readiness score is built on data I can capture passively — sleep, heart rate, training load. But the picture is incomplete without the biomarkers you can only get from a lab: testosterone, cortisol, thyroid, iron, vitamin D. I want to layer those in as periodic inputs and see how they correlate with the patterns the system is already tracking.
Why it compounds
A single readiness check on a single morning changes nothing. But months of slightly better decisions — resting when Zeus says rest, eating more protein because he told me at lunch I was behind, catching illness two days before symptoms — adds up.
The tools to build systems like this used to be gated behind engineering skills. They’re not anymore. Not because AI replaces expertise. Because it lets people with domain knowledge act on it in ways that used to require someone else’s hands.
Comments