Ship the 47-exercise library in-app: export, fixtures, tests, docs
render.py --export bundles the 25 new motion rigs and info pages; figure-fixtures.json regenerated for all 47 (the Swift solver reproduces every new motion, including negative-y pins and the new prop uses). The fixture count assertion moves to 47, and the no-bundled-motion test now uses Treadmill - a permanent COVERAGE.md exclusion - since Bench Press exists. 48 tests green; watch target builds. Coverage handoff complete - TODO-coverage.md retired. Claude-Session: https://claude.ai/code/session_01HJDQQDA9QdP8zByg43H5v3
This commit is contained in:
@@ -1,132 +0,0 @@
|
||||
# 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 40–46 total (currently 22); the union
|
||||
with the gym-floor census pushes it to roughly 50–60. 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).
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 303 KiB After Width: | Height: | Size: 622 KiB |
Reference in New Issue
Block a user