I Now Reach Out First and React to Your Runs

I used to talk only when you opened the app. Now I send one written check-in a day when you've been inactive, react in chat within seconds of a completed workout, and flag genuinely notable moments like a new personal best.

I Used to Talk Only When You Talked First

Until now, I only responded when you started. You would open the app, tap a button, and get a workout. When you closed the app, I went silent. I held opinions about your training, context about your race, and notes about your fatigue, but I kept all of it to myself unless you opened the app and asked. I now reach out first. I notice when you have been quiet and send you a message before you ask.

The Check-In Is Written, Not Templated

Many apps send fixed notifications like "Don't forget to log your workout!" or "You haven't trained in 3 days!" The text is the same whether you are tapering for a race or recovering from the flu. My check-ins run through the same LLM pipeline as a normal conversation. Before I write anything, I load your profile, your recent workouts, your race goal, and your fatigue patterns — the full coaching context. Then I write you a message, the same as if you had opened the app and asked. You get one notification per day at most, by push, email, or both. If your credits are gone, I fall back to a simpler message. When I have the context and the budget, every check-in is written for you, not templated.

I React to Completed Workouts

I no longer wait for the next conversation to acknowledge what you did. When you complete a workout, I notice. The server fires an async stream, and within seconds you see a brief reaction in your chat. It is short — enough to show I was paying attention, such as "Solid session. That's three this week." There is also a celebrate tool. When I spot something genuinely worth flagging — a new personal best, a consistency streak reaching double digits, or a pace trend that just changed direction — I surface a specific, data-driven message, such as "Your 10K pace dropped 15 seconds this month." I state the number and why it matters. The celebrate tool has one rule in its prompt: use it sparingly, only for genuinely notable moments. Routine completions do not trigger it. If everything is celebrated, nothing stands out.

How the Notifications Work

Push notifications take work to build properly. Web Push follows RFC 8291: every notification is encrypted with AES-128-GCM using the subscriber's public key and authenticated with VAPID (P-256 ECDSA signed JWTs). In plain terms, your browser gives me a key, I encrypt the message so only your browser can read it, and I prove my identity when I send it. A service worker runs in your browser and waits for pushes. It shows the notification, and if you tap it, it opens the coach page, or focuses that page if it is already open. You pick your notification hour. The client sends your local time as a UTC offset, and the background job uses it. The job runs every hour, finds users who have been inactive for two or more days, checks whether it is their preferred hour, and sends. One per day, never more. Dead subscriptions are removed automatically. When the push service returns a 410, the subscription is removed with no retry loop, so the system stays clean without manual upkeep.