Files
workouts/Exercise Library/TODO-coverage.md
T

133 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Handoff: right-size the exercise library by functional coverage
Repo: `~/Documents/indie/Workouts`. Read `Exercise Library/SYSTEM.md` first
(motion format, props, visual language), then one machine motion
(`Leg Press/motion.json`) and one bodyweight motion (`Bird Dog/motion.json`)
as templates, one `info.md` (`Leg Press/info.md`) plus its parser
(`Workouts/ExerciseFigure/ExerciseInfo.swift` — it parses a fixed shape, not
general Markdown), and `render.py` (`--sheet`, `--strict`, `--orbit`,
`--export`, `--fixtures`).
## The question this session answers
Not "how many exercises" but "which movement patterns can a user not log?"
The picker (`ExercisePickerView`) lists exactly the bundled library names and
there is no free-text fallback — the library is the app's **closed catalog**.
A missing pattern is a hard wall, not a cosmetic gap. Build the coverage
model, audit against it, then author the gap-fillers in priority order.
## The coverage model (starting point — refine it, don't rubber-stamp it)
Two axes, and the target list is their **union**:
1. **Function — a movement-pattern × modality matrix.** Patterns: squat,
hinge, lunge, horizontal push, vertical push, horizontal pull, vertical
pull, elbow flexion, elbow extension, shoulder raise (lateral/rear), hip
ab/adduction, calf, core anti-extension, core rotation, core lateral,
core flexion, mobility/warm-up. Modalities: machine, free weight
(barbell/dumbbell), bodyweight/floor. A cell needs an exercise only if
real programs train that pattern that way.
2. **Equipment — a gym-floor census.** Walk a typical commercial gym
(Planet Fitness / Golds tier): every common machine and free-weight
station should have at least one library entry, because users log by
station name, not by pattern — the matrix calls horizontal push "covered"
by Chest Press, but Bench Press, Dumbbell Bench Press, and Pec Deck are
distinct stations people expect to find in the picker. Inclusion test:
"found in most gyms," not "exists somewhere."
The test for "done": a typical gym-goer — machine circuit, free-weight
lifter, or home/bodyweight — can build their whole program from the picker
without a missing pattern *or* a missing station. Write both filled tables
into SYSTEM.md (or a COVERAGE.md beside it) so future additions are judged
the same way.
## What a rough audit already shows (verify, then prioritize)
- **Hinge: zero coverage in any modality** — no Deadlift, Romanian Deadlift,
Glute Bridge, or Hip Thrust. The single biggest hole; glutes are basically
untrained by the current catalog.
- **No lunge pattern** (Lunge / Split Squat).
- **Bodyweight column missing its canon**: Squat, Push-Up, Pull-Up.
- **Free-weight column completely empty** — zero barbell/dumbbell exercises.
The `dumbbell` prop type exists in both renderers but has never been used
by a motion; its first real use may shake out bugs.
- **Shoulder raise**: no Lateral Raise (machine Shoulder Press only).
- **Core flexion**: no plain Crunch (machine Abdominal only).
- **Census gaps** — the current 14 machines are the standard selectorized
circuit (good coverage there), but common stations are absent: bench
press / incline bench (barbell + dumbbell), squat rack / Smith machine,
pec deck (+ rear-delt fly), the cable station's staples (triceps
pushdown, cable curl, cable crossover, face pull), assisted dip /
pull-up, hack squat, back extension (roman chair), hip thrust, and the
whole dumbbell rack (rows, shoulder press, flys, lateral raises, curls,
RDLs, lunges, goblet squat).
- Memory notes a desired "morning wake-up" mobility set (Cat-Cow exists;
neck rolls, arm circles, etc.) — decide whether it's this session or the
next phase.
The pattern matrix alone lands around 4046 total (currently 22); the union
with the gym-floor census pushes it to roughly 5060. The tables decide
which ones and in what order: hinge first, then the bench/rack/dumbbell
free-weight canon and bodyweight staples, then the remaining stations
(cables, pec deck, assisted machines), then isolation/mobility.
## Authoring workflow, per exercise
- New folder `<Name>/` with `motion.json` + `info.md`. The folder/`name`
string is user-facing (picker + run screen) — match the existing naming
register.
- Pose keyframes in anatomical angles per SYSTEM.md; run
`python3 render.py --strict "<Name>"` (ROM violations are data bugs; a few
legacy warnings exist in old motions, add none), eyeball `preview.gif` AND
`orbit.gif` — every exercise orbits in-app now, so check ±45°/90°/180°,
not just the authored view.
- Machines need props: scene slabs carry `z`/`depth` (see SYSTEM.md props
section), `bar`/`pad`/`roller`/`cable` ride joints. Free weights are
usually just a `bar` (with `plateR`) or `dumbbell` at the hands.
- `info.md` must follow the parsed shape: `# Title`, summary paragraph,
the `**Category:** / **Type:** / **Targets:** / **Prescription:**` bullets,
then `## Setup / Execution / Cues / Common Mistakes / Progression`.
**Machine exercises' `Type:` must start "Machine-based"** — that prefix is
what shows the machine-settings UI (`ExerciseInfo.isMachineBased`).
## Invariants — do not break
- **Data-only expansion.** New exercises need zero Swift changes; if you find
yourself touching the schema or solver, stop and re-read SYSTEM.md — and
any schema change must land in `render.py`/`kinematics.py` and the Swift
port in lockstep, fixtures regenerated.
- `WorkoutsTests/ExerciseMotionTests.swift` asserts
`fixtures.exercises.count == 22` — bump it to the new count and regenerate
with `python3 render.py --fixtures`. `allBundledMotionsBuildTimelines`
covers new motions automatically.
- Starter splits and their fixed-ULID seeds are frozen — adding library
exercises must not touch `StarterSplits/` or `Workouts/Seed/`.
- Every exercise ships both files: a motion with no `info.md` renders a blank
reference page in Settings → Library.
## Verification workflow
`python3 render.py --strict` (whole library) + `--sheet` and eyeball;
`--orbit` for each new machine; `python3 render.py --export` then
`python3 render.py --fixtures`; `xcodebuild test -scheme Workouts
-destination 'platform=iOS Simulator,name=iPhone 17 Pro'
-only-testing:WorkoutsTests` (48 green today; count assertion updated);
`xcodebuild build -scheme "Workouts Watch App" -destination
'generic/platform=watchOS Simulator'`. If test results ever contradict the
source, suspect a stale incremental build — nuke DerivedData and rerun.
One end-user CHANGELOG.md sentence per the app-changelog skill (e.g. the
library doubles with deadlifts, lunges, push-ups, dumbbells…), README
key-features line if it names library scope. Commit in reviewable batches
(the coverage model + audit first, then exercises by pattern group), push,
delete this file in the final commit.
## Judgment calls you're empowered to make
The final matrix rows and which cells count as "required"; where the census
draws its "most gyms" line (kettlebells, T-bar row, pullover machine, and
cardio equipment are likely out; Smith machine is borderline); whether the
cable station gets one entry per exercise or per pattern; the exact
exercise picks and their names; whether the mobility/"morning wake-up" set
is in scope or explicitly deferred to the next phase; per-exercise camera
yaw and prop minimalism (schematic silhouettes, never scale models).