AI-assisted endurance coach for runners and cyclists. Pulls activities from Strava, builds periodized training plans grounded in your real fitness baseline, and adjusts daily sessions based on a manual readiness check-in.
There is no human coach in the loop. Periodization, daily adjustments, and activity feedback are all generated by Azure AI Foundry agents wrapped in deterministic training-science guardrails (G1–G5) that fail closed if the AI proposes anything physiologically unsound.
Status: Phase 1 scaffolding. All packages compile and unit tests for the training-science guardrails pass. Next.js app boots and the check-in flow is end-to-end. Plan generation and coach chat are wired through the governance layer but require a configured Azure AI Foundry project to actually run.
- Application stack and requirements - current stack, functional requirements, non-functional requirements, constraints, and validation commands.
- Strava-only data source (v1). OAuth sign-in. Pulls activities + streams.
- Manual daily check-in for readiness, sleep, RHR, soreness, injured/sick
flags. Future-proofed via a
WellnessAdapterinterface (Oura/Whoop/Garmin drop in later). - Deterministic training science: Banister TRIMP, Coggan TSS, EMA-based CTL/ATL/TSB, Karvonen HR zones, Coggan power zones, Daniels-style target paces, 3σ outlier rejection on baseline.
- Five guardrails wrap every AI call:
- G1 — Physiological rules: ≤10% weekly volume ramp, ≥1 rest day, no back-to-back hard days, recovery week every 4th, taper, long-run cap, goal-feasibility check (green/amber/red).
- G2 — Daily readiness: deterministic level + allowed-action enum; injured/sick → forced pause; TSB < -25 for 3+ days → forced deload.
- G3 — Agent governance: per-agent tool allowlist, prompt-injection pattern blocklist, rate limits, append-only audit log with no user content.
- G4 — Data quality: refuses plan generation with < 4 weeks history or < 8 activities, surfaces what the user must self-report.
- G5 — Schema validation: every Foundry agent output is validated by zod; rejected outputs trigger 1 retry then deterministic fallback.
- Azure AI Foundry hosted agents managed by a local JSON manifest +
PowerShell sync script (
pnpm agents:sync).
apps/
web/ Next.js 16 (App Router) + NextAuth/Auth.js (Strava) + dashboard + calendar
worker/ BullMQ workers: strava-sync, training-load, activity-summary
packages/
db/ Prisma schema + client
training/ Pure TS: TRIMP, TSS, CTL/ATL, zones, paces, baselines, rules, readiness
strava/ Typed Strava v3 client + rate limiter (100/15min, 1000/day)
ai/ Foundry REST client + governance wrapper + zod schemas + policy.yaml
agents/
foundry-agents.json Local manifest of agents to upsert into Foundry
scripts/
sync-foundry-agents.ps1
- Node >= 22.12.0
- pnpm 11.0.9 (
corepack enable && corepack prepare pnpm@11.0.9 --activate) - Docker Desktop (for local Postgres + Redis)
- Azure CLI + an Azure AI Foundry project (only needed once you want plan/chat agents to run)
- A Strava API application
pnpm installnode -e "console.log(require('crypto').randomBytes(32).toString('base64'))"Copy the value. You'll paste it into TOKEN_ENCRYPTION_KEY next.
- Go to https://www.strava.com/settings/api and create an application.
- Set Authorization Callback Domain to
localhost. - Copy the Client ID and Client Secret.
cp .env.example .envFill in:
STRAVA_CLIENT_ID,STRAVA_CLIENT_SECRET— from step 3.TOKEN_ENCRYPTION_KEY— from step 2 (32 bytes, base64).NEXTAUTH_SECRET— generate withopenssl rand -base64 32.AZURE_FOUNDRY_PROJECT_ENDPOINT,AZURE_FOUNDRY_MODEL,AZURE_FOUNDRY_AGENT_PREFIX— only needed when you want to actually run the AI agents. Readazure.mdbefore configuring.
docker compose up -dpnpm db:generate
pnpm db:migrate# Terminal 1
pnpm --filter @coaching/web dev
# Terminal 2
pnpm --filter @coaching/worker devOpen http://localhost:3000 and sign in with Strava.
The app relies on Foundry agents for plan generation, daily adjustments, and activity summaries. Without this step the AI features fail closed (you'll still get sync, dashboard, calendar, and check-in).
Once azure.md is filled in and you've run az login:
pnpm agents:syncThis will create or update four agents in your Foundry project. The script
uses ShouldProcess and will prompt before each upsert; pass -Confirm:$false
to skip prompts in CI.
pnpm -r testReference values for TRIMP, CTL/ATL, readiness, and rule validation are covered
by golden tests in packages/training/test/ and packages/ai/test/.
MIT — see LICENSE.
- No Garmin Connect integration. The Garmin Connect Developer Program
requires business approval; out of scope for a personal project. The
WellnessAdapterinterface lets it drop in later. - No HRV / sleep / recovery from Strava. Strava has no such endpoints; the manual check-in is the v1 wellness source.
- No workout push to Strava. Strava only accepts uploads of completed activities (FIT/TCX/GPX), not planned workouts. The plan lives in-app.
- No medical, nutritional, or pharmacological advice. The coach agent refuses these and recommends a qualified professional.