EvoVelocity JSON — Required & Optional Changes (Summary) 🔒 Core design rules (locked) Velo drills Must always have intent May optionally have reads ❌ Never reads without intent Strength drills Must always have rpe_target May optionally have reads (e1RM) ❌ Never reads without rpe_target Routine Mode Requires no Routine-specific JSON Fully consumes the same fields as Classic Mode 1️⃣ Velo drills — intent (REQUIRED) Every throwing / hitting velo-related drill must include: "intent": "controlled" Allowed intent values (locked vocabulary) recovery | controlled | build | high | max Example — Velo drill (intent only) { "id": "pivot_pickoff", "category": "throwing", "intent": "controlled", "sets": 3, "reps": 8 } 2️⃣ Velo drills — intent + reads (OPTIONAL) Use when you want measured output (arm velo / exit velo). Example — Max intent velo drill { "id": "pulldown_max", "category": "throwing", "intent": "max", "sets": 5, "reps": 1, "reads": { "enabled": true, "required": false, "type": "PITCH_VELO", "unit": "mph", "mode": "max_of_attempts", "attempts_expected": 5, "bind_goal_type": "ARM_VELO", "allow_skip_measurement": true } } What this enables Intent → effort adherence (Easy/Challenging/Hard) Reads → performance tracking Feeds Session Quality → Insights v1–v3 3️⃣ Strength drills — RPE (REQUIRED) Every strength drill must include: "rpe_target": 7 Optional but strongly recommended: "rpe_band": [6.5, 7.5] Example — Strength drill (RPE only) { "id": "db_split_squat", "category": "strength", "sets": 3, "reps": 8, "rpe_target": 6.5, "rpe_band": [6, 7] } What this enables RPE target display RPE helper card Effort adherence via Easy/Challenging/Hard Session Quality accuracy 4️⃣ Strength drills — RPE + e1RM reads (OPTIONAL) Only for selected lifts: Bench Squat Deadlift Example — Strength drill with e1RM { "id": "deadlift", "category": "strength", "sets": 4, "reps": 5, "rpe_target": 7, "rpe_band": [6.5, 7.5], "reads": { "enabled": true, "required": false, "type": "E1RM", "unit": "kg", "mode": "calculated", "bind_goal_type": "DEADLIFT", "allow_skip_measurement": true } } What this enables e1RM tracking Strength → Velo Transfer Signal (Insights v3) Quality-weighted analysis (via Session Quality) 5️⃣ Reads block — unchanged, but now contextual Your existing reads structure is correct and does not need changes. What changed is how the app interprets it: Reads present? Meaning Yes Drill is a performance expression No Drill is execution-focused only Reads do not affect Session Quality directly — intent/RPE adherence does. 6️⃣ No new JSON for Routine Mode (important) Routine Mode: does not require flags does not require duplication consumes existing drill metadata: intent rpe_target reads (Optional future hint — NOT required) "routine_hint": true You can ignore this for now. 7️⃣ Optional pack-level defaults (nice-to-have, not required) If you want to reduce repetition later: "defaults": { "strength": { "rpe_target": 7, "rpe_band": [6.5, 7.5] }, "velo": { "intent": "controlled" } } Drill-level values override defaults. 8️⃣ What NOT to add to JSON (locked exclusions) ❌ Drill-level notes ❌ Pain scores ❌ Per-set RPE logging ❌ Drill timestamps ❌ Intent scoring fields ❌ Routine-mode flags ❌ Insight configuration blocks All intelligence is derived, not stored. 9️⃣ How JSON now feeds Insights (one-glance summary) Feature JSON Field Velo intent adherence intent + effort feedback Strength effort adherence rpe_target + effort feedback Performance tracking reads Session Quality Derived Load Match Session readiness + feedback Weekly patterns Aggregated Transfer Signal e1RM + velo reads, weighted by Session Quality ✅ Final checklist for each drill (use this to validate packs) Velo drill Has intent If reads exists → intent exists Reads only where output matters Strength drill Has rpe_target If reads exists → rpe_target exists e1RM only on approved lifts Final takeaway (one sentence) Your JSON now cleanly separates intent (how hard), execution (effort), and measurement (reads), and Routine Mode consumes all of it without compromise.