Back to catalog

health-log-analysis

Analyze Amazfit workout screenshots with health log data.

Category 💰 Wealth

Health Log Analysis

Trigger

User shares an Amazfit/smartwatch screenshot or workout data and asks for analysis or logging.

Step 1: Prepare Images for Extraction

Before calling vision_analyze, check image dimensions. DeepSeek vision (aux model) fails on images >2000px tall.
python3 /opt/data/scripts/vision-crop.py <image_path>

This outputs section PNGs to /tmp/vision_sections/. If only 1 section, use it directly. If multiple sections, call vision_analyze on each section separately and merge results.

Step 2: Extract Everything from the Screenshot

If ChatGPT extraction text is provided, use it as the primary source — it's more reliable for dense tables. Cross-check against vision model output for obvious errors.

If only screenshots are available, use vision_analyze on the cropped sections.

Pull ALL available data, not just summary numbers:

  • Summary: distance, time, avg/max pace, avg/max HR, calories
  • HR zones: % time in each zone (the Amazfit "Training Effect" screen or HR zone chart)
  • Biomechanics: cadence, stride length, vertical oscillation, ground contact time, power
  • Environment: temperature, humidity (Amazfit often shows this)
  • Splits: per-km pace and HR
  • Performance index: real-time performance score if shown
  • Training effect: aerobic TE, anaerobic TE, workout balance

Step 3: Read the Health Log

File: wiki/self/health/2026 Health Log.md

Read enough history to identify trends — not just the last 2-3 entries. Look for:

  • Weight trajectory (weekly/monthly direction)
  • Pace trends for similar distances
  • HR trends at similar paces (fitness progression)
  • Cadence/stride consistency over time
  • Resting HR and HRV trends (recovery readiness)
  • Training load patterns (hard/easy balance)
  • Any health notes (wheezing episode, injuries, etc.)

Step 4: Analyze Like a Coach

Interpret the data, don't just restate it:

  • Cardiac drift: HR climbing while pace stays flat = dehydration or heat stress. Name it when you see it.
  • Mechanical consistency: Did cadence/stride hold up across splits? Deterioration = fatigue or poor form under load.
  • HR zone distribution: What % of the run was aerobic vs threshold vs VO2? Does this match the intended session type?
  • Pace variability: Smooth splits = good economy. Spikes/drops = fatigue points or terrain.
  • Performance index trend: Watch's own assessment of fitness relative to baseline.
  • Training load context: Where does this sit in the week/month? Overloaded or undertrained?

Step 5: Advice — ONLY if Rooted in Data

The rule: If you can't point to a specific number or trend from his data or health log history, don't give advice.

Good (data-rooted):

  • "Your cadence dropped from 160 to 154 — worth watching if it persists over multiple runs"
  • "This is your 3rd run in 3 weeks. Your last consistent stretch was Jul 6–29 where you hit 100 km in the month"
  • "HR was 131 avg at 10'42" pace. On Jul 28 you ran 10'42" at 144 avg — your aerobic efficiency has improved since then"

Bad (generic):

  • "Make sure to stay hydrated"
  • "Consider adding interval training"
  • "Good job, keep it up!"
  • "Don't forget to stretch"

If there's nothing actionable from the data, say so. A clean "this was a solid aerobic session, nothing unusual in the data" is better than padding with generic tips.

Step 6: Log to Health Log

File: wiki/self/health/2026 Health Log.md

Summary table — add row if not already there. Detailed entry — structured with:
  • Weight (if provided)
  • Morning Readiness section (if pre-activity screenshot provided): RHR, HRV, sleep duration + deep/REM, fatigue level, fitness level, exertion load, training status, waist (if measured). Skip if not provided.
  • Activity & Training section with full metrics (skip Location and Device — always the same). Include Conditions (temp/humidity) if provided.
  • Brief insight paragraph grounded in data — interpret, don't just restate. Note unusual patterns, explain why they occurred, flag anything worth watching. This is the value-add for weekly/monthly review.
Update the monthly total row — the summary table has a | Total | | 64.38 | row at the bottom. After adding a new row, recalculate the sum of all km values in that month's table and update the total. Use Python to sum, don't do mental math. Do NOT log a comparison table — the daily entries already contain all the data needed for comparison. Comparisons belong in the Slack conversation or weekly retro, not the health log. Log to self/2026.md too — add a one-liner under the current week's date heading with key highlights (weight, distance, pace, notable HR/TE values, any notable context like fasting). The health log is the detailed source of truth; self/2026.md is the cross-bucket running log that retro reads.

Pitfalls

  • Don't assume weather data if it's not in the screenshot
  • Don't give nutrition advice unless he has his actual intake data from the log
  • Don't compare across different activity types (jog vs walk vs home workout) unless explicitly asked
  • Cadence range for Joseph: typically 149-160 spm on jogs. Below 150 = tired or casual pace.
  • Joseph's VO2 Max has been stable at 33 — don't treat it as a fitness concern unless it drops
  • Weight range: typically 77.3–78.4 kg. Don't flag fluctuations within this range.
  • Location and Device are constant (Panchkula, Amazfit Active 2) — never log them.
  • DEVICE: Amazfit Active 2. NOT Garmin, NOT Apple Watch, NOT Fitbit. The companion app is Zepp (formerly Amazfit). If the vision model says "Garmin" or "Garmin Connect", it is wrong — correct it. Screenshots are always from the Amazfit/Zepp app.
  • When ChatGPT extraction is provided alongside screenshots, use it as the authoritative source for numbers. My vision model garbles table data (splits, HR zones, training load). ChatGPT extraction is more reliable for: exact duration, distance, max HR, training load, per-km splits, HR zone percentages. Cross-check against health log history for reasonableness.
  • DeepSeek vision (via OpenCode Go) can't handle large images. If the screenshot is >2000px tall, crop into sections (top summary, HR zones, splits) and extract each separately. The aux vision model is now deepseek-v4-flash-vision-exp (better than minimax-m3 for tables).

Step 7: Verify the Write (MANDATORY)

After writing to the health log AND to self/2026.md, run the file-based eval to confirm the writes landed:

python3 /opt/data/wiki/produce/hermes/hermes-evals/runners/run_file_checks.py 2>&1 | grep -A2 "health_log"

If the check shows FAIL, tell Joseph immediately what failed and fix it before moving on. Do not silently proceed.

If the check shows PASS, confirm briefly: "Health log updated and verified."

This is the quality gate — the eval runs as part of the skill, not as a separate step Joseph has to ask for.