# PLAN.md — MVP implementation tracker This is the working tracker for the hackathon build. `PROJECT.md` explains the product and architecture; `DECISIONS.md` records decisions. This file answers: where are we, what is done, what is next, and what decisions are blocking implementation. --- ## Current status **Current phase:** Phase 7 — Persistence / Phase 8 — Submission readiness **Current task:** prove the local daily loop end to end, then configure/deploy the optional Hugging Face Dataset persistence. **Next decision gate:** decide the actual private Dataset repo id and Space secret setup. **Training-rule source:** `hypertrophy_app_training_rules.md`. **Local app:** running at `http://127.0.0.1:7860` when started with: ```bash scripts/reset_server.sh ``` **Test command:** ```bash .venv/bin/python -m unittest discover -s tests ``` --- ## Phase 0 — Project alignment **Goal:** lock the MVP direction and hackathon strategy. **Status:** Done - [x] Read `AGENTS.md`, `PROJECT.md`, and `DECISIONS.md`. - [x] Decide that the MVP includes text-first check-in extraction. - [x] Decide that the parser may use a small model, but the engine remains deterministic. - [x] Decide that the engine receives only structured data. - [x] Decide storage path: interface first, local JSON first, Hugging Face Dataset later. - [x] Add hackathon optimization goals to `PROJECT.md`. --- ## Phase 1 — Real MVP UI shell **Goal:** make the first screen match the real daily loop before real parser/engine logic exists. **Status:** Done for first scaffold - [x] Create runnable Gradio app. - [x] Convert app to `gr.Blocks`. - [x] Add `Today` tab. - [x] Add natural-language check-in box as the main input. - [x] Add editable structured fields for time, energy, sleep, soreness/constraints, pain/injury, and mood/stress. - [x] Show hardcoded session preview. **Not done yet:** - [x] Replace manual structured fields with parser-filled fields. - [x] Replace hardcoded preview with engine output. --- ## Phase 2 — Core schema **Goal:** define the shared data contract before parser, engine, logging, and persistence. **Status:** Done for MVP schema **Done:** - [x] Decide schema implementation: Pydantic. - [x] Create `training_coach/` package. - [x] Add `CheckIn`. - [x] Add `PainIssue`. - [x] Add `ParsedCheckIn`. - [x] Add `ContextSignal`. - [x] Add `Exercise`. - [x] Add anatomical `Muscle` enum. - [x] Add `PrescribedSet`. - [x] Add `PlannedExercise`. - [x] Add `SessionPlan`. - [x] Add `LoggedSet`. - [x] Add `LoggedExercise`. - [x] Add `SessionLog`. - [x] Add model tests. **Current models:** - `CheckIn` - `PainIssue` - `ParsedCheckIn` - `ContextSignal` - `Exercise` - `Muscle` - `PrescribedSet` - `PlannedExercise` - `SessionPlan` - `LoggedSet` - `LoggedExercise` - `SessionLog` **Next tasks:** - [x] Decide and add `LoggedSet`. - [x] Decide and add `SessionLog`. **Known future schema additions:** - [ ] Exercise equipment, deferred until equipment availability/substitution matters. - [ ] Supersets, drop sets, rest-pause, and other advanced set types, deferred until the classic-set MVP works. --- ## Phase 3 — Small model parser **Goal:** convert natural-language check-ins into validated `CheckIn` objects. **Status:** Done for MVP parser **Decision status:** - [x] Choose local parser model: Ollama `qwen3:1.7B`. - [x] Replace the Hugging Face Spaces Transformers parser with a GGUF llama.cpp path. **Acceptance rule:** - Local development/evaluation now prefers Ollama because quantized llama.cpp/Metal inference is much faster on the Mac than local Transformers CPU/disk-offload. - Current local parser default: `qwen3:1.7B`, chosen for MVP parser speed. **Tasks:** - [x] Add parser output schema with missing fields, structured follow-up items, display follow-up questions, and context signals. - [x] Create parser module. - [x] Define strict JSON prompt/output format. - [x] Fix parser keys and enum values through schema validation. - [x] Validate model JSON into `ParsedCheckIn`. - [x] Add optional local Transformers runtime wrapper. - [x] Add parser backend selector for local Ollama vs Space llama.cpp runtime. - [x] Add Ollama local runtime wrapper with JSON-schema structured outputs. - [x] Add GGUF llama.cpp runtime wrapper for Hugging Face Spaces CPU deployment. - [x] Run the model on one fixture and parse raw text into `ParsedCheckIn`. - [x] Run the model against all acceptance fixtures. - [x] Remove overfit fixture-shaped prompt examples. - [x] Replace canned keyword follow-up triggers with LLM-proposed structured `follow_up_items`. - [x] Add deterministic cleanup for duplicate, already-answered, or unsupported follow-up questions. - [x] Add deterministic parser cleanup for obvious missing muscle mappings. - [x] Remove stale/repetitive sleep follow-up questions when sleep hours and quality are already known. - [x] Add parser tests/fixtures under `tests/fixtures/`: - [x] short time + poor sleep + low energy - [x] soreness/pain constraint - [x] ambiguous check-in requiring `unsure` or notes - [x] adjacent context signal such as "yesterday I ran a 10k" - [x] high energy + long session - [x] Wire parser output into editable UI fields. **Current parser evaluation result:** - `Qwen/Qwen2.5-1.5B-Instruct` passed 1/5 acceptance fixtures on the first full local run. - Main failures: missed explicit "no pain", over-asked for sleep hours, produced markdown code fences for some JSON, missed the 10k context signal, and added unrelated pain notes. - Local Transformers `Qwen/Qwen3-4B` was too slow on Mac because it offloaded to disk. - Ollama `qwen3:8b` completed the same fixture run much faster and passed 2/5 under the current strict exact-match evaluator. - Ollama `qwen3:8b` produced valid schema-shaped JSON, but needs tighter fixed context labels and a less brittle evaluator for free-text notes/follow-up wording. - Context signal labels are now fixed enum values, and the evaluator now treats free-text notes/follow-up wording semantically while keeping labels/enums/numbers strict. - Ollama `qwen3:4b` is installed and passed 2/5 acceptance fixtures. Main failures: missed mapping "tricep" to `triceps_brachii`, omitted follow-up questions for the 10k context signal, and failed one semantically acceptable ambiguous-pain follow-up due to evaluator wording. - We no longer treat 5/5 one-shot fixture passing as the main goal. The product behavior is now multi-round: parse what is clear, ask structured follow-up questions, then build a session once the structured check-in is good enough. - The Today UI now uses a chat-style check-in conversation and updates editable fields after each message. - Parser output is now wired into the editable Today UI fields. --- ## Phase 4 — Engine slice **Goal:** build deterministic session plans from structured check-ins and history. **Status:** Done for MVP spine **Blocked by:** your training rules. **Important rule:** no training logic gets invented by the agent. When engine work needs a rule, it must come from you and be recorded in `DECISIONS.md`. **Tasks:** - [x] Decide MVP split and exercise list. - [x] Decide exercise order. - [x] Encode fixed 4-day template in `training_coach.engine`. - [x] Preserve per-exercise rest targets in `PlannedExercise`. - [x] Add unit tests for the fixed 4-day template. - [x] Decide how to select today's training day. - [x] Decide minimum completed-session fields for MVP logging. - [x] Implement next-day state from completed session logs. - [x] Add local JSON history storage. - [x] Decide first readiness/time adaptation rules. - [x] Implement readiness set/RIR modifiers. - [x] Implement pain/injury exercise filtering using muscle tags. - [x] Implement time compression from `time_available_minutes`. - [x] Decide double-progression MVP load increment. - [x] Decide double-progression rep range rule. - [x] Implement double progression: add reps before load, then +1 kg and reset reps. - [x] Implement pure Python `build_session_for_day(...)` entry point. - [x] Add unit tests for every encoded MVP rule. **Current fixed template:** - [x] Day 1: Pullover, row, incline bench, incline fly, goblet squat. - [x] Day 2: Skullcrusher, lateral raise, triceps extension, cable lateral raise, barbell curl, hip thrust, standing calf raise. - [x] Day 3: Incline bench, incline fly, row, pullover, Romanian deadlift. - [x] Day 4: EZ-bar curl, lateral raise, hammer curl, cable lateral raise, triceps extension, goblet squat, standing calf raise. **MVP simplification:** - [x] All exercise rests are normalized to 1 minute for now. - [x] Double progression uses fixed +1 kg load jumps for now. - [x] Single-rep template prescriptions become 5-rep ranges with the original rep target as the middle value. - [x] Pain filtering removes affected exercises instead of substituting replacements. - [x] Time compression cuts later/lower-priority sets first. - [x] Readiness modifies set count and target RIR. --- ## Phase 5 — End-to-end daily loop **Goal:** check-in text produces a real deterministic session plan. **Status:** Done for local MVP **Tasks:** - [x] Parser extracts `CheckIn`. - [x] Parsed fields are visible/editable. - [x] Engine builds `SessionPlan`. - [x] UI renders session clearly enough to train from. - [x] Keep explanation factual and based on engine output. --- ## Phase 6 — Logging **Goal:** record what actually happened in training so the next session and double progression have real history. **Status:** Done for local MVP **Tasks:** - [x] Decide MVP completed-session shape for day tracking and progression. - [x] Add performed-set logging UI. - [x] Save actual reps/loads. - [x] Save the completed training day number. - [ ] Attach logs to the planned session/check-in. Deferred by the minimal-history MVP compromise. - [x] Derive next suggested day from the last completed day. - [x] Add tests for log serialization. --- ## Phase 7 — Persistence **Goal:** make training history survive restarts and deployments. **Status:** Local persistence done; durable deployment persistence next **Tasks:** - [x] Create storage interface. - [x] Add local JSON storage. - [x] Add Hugging Face Dataset storage. - [x] Load history on startup. - [x] Append completed session logs. - [ ] Prove restart survival. --- ## Phase 8 — Submission readiness **Goal:** make the app demoable and optimized for the hackathon. **Status:** Not started **Tasks:** - [ ] Deploy to Hugging Face Space. - [ ] Add proof-of-use view from real logs. - [ ] Write field notes. - [ ] Record short demo video. - [ ] Prepare submission copy. --- ## Phase 9 — Stretch **Goal:** only after the MVP spine works. **Status:** Not started - [ ] Coach-style narration. - [ ] Progress charts. - [ ] Better parser model. - [ ] Tiny Titan route. - [ ] Research-reader. - [ ] Fine-tuning. - [x] llama.cpp route. - [ ] Custom UI polish. --- ## Immediate next step Prove the local spine with one manual end-to-end training loop, then implement durable Hugging Face Dataset persistence so the deployed Space does not lose history. Proposed starting point: ```txt messy check-in + local history -> adjusted session -> completed log ``` Use the app with a few intentionally messy check-ins and inspect whether the plan notes explain every modification.