| # DECISIONS.md — Decisions log |
|
|
| A living record of what's decided and what's still open. The agent should treat |
| "Decided" items as fixed and "Open" items as **mine to decide** — when an open item is |
| needed, ask me rather than choosing. When I make a call, move it from Open to Decided |
| with a one-line note on why. |
|
|
| --- |
|
|
| ## Decided |
|
|
| - **Hackathon track:** Backyard AI (solving my own real problem). |
| - **Users:** single user (me). No multi-profile. |
| - **Goal:** hypertrophy + continuous progress; lean bulk (slight surplus or maintenance). |
| - **Architecture:** deterministic Python engine (no AI) + small-model parser layer for |
| language only. The parser turns free-text check-ins into structured fields; the engine |
| receives only structured data and never calls AI. (See `PROJECT.md`.) |
| - **MVP input flow:** hybrid first, text-first by MVP completion. The UI starts with a |
| natural-language check-in plus editable structured fields; a small model parser is |
| included in the MVP. |
| - **Build order:** UI shell first, then schema, small-model parser, deterministic engine, |
| logging, persistence, deployment, and real-use proof. |
| - **First progression rule:** double progression (hit top of rep range on all sets → |
| add load next time). More rules added later from my research. |
| - **MVP load increment:** double progression uses a fixed +1 kg load increase when all |
| sets for the latest matching exercise exposure hit the top of the prescribed rep |
| range. Slower, consistent progression is preferred over aggressive jumps that risk |
| early failures and plateaus. |
| - **MVP rep progression:** single-rep template prescriptions become a 5-rep progression |
| range with the supplied reps as the middle target. Example: `13` becomes range |
| `11-15` with initial target `13`. If the top is not hit, keep load and add up to |
| `+2` reps next exposure. If the top is hit on all sets, add `+1 kg` and reset target |
| reps to the low end of the range. |
| - **Training rule source:** `hypertrophy_app_training_rules.md` is the canonical guide |
| for evidence-based engine behavior. Encode only explicit rules from that document or |
| later user decisions; when the guide gives a range, ask for the concrete MVP default |
| before implementing. |
| - **Hosting/stack:** Gradio app on a Hugging Face Space; persistence via a Hugging Face |
| Dataset; GitHub repo with the Space as a second remote. |
| - **Persistence path:** use a storage interface; start with local JSON for fast |
| development, then add Hugging Face Dataset storage for durable deployment. |
| - **Persistence badge compromise:** local JSON remains the default so the app can run |
| fully locally with no cloud dependency. Hugging Face Dataset storage is optional and |
| enabled only by deployment environment variables; it is durable storage, not cloud AI |
| inference or engine logic. |
| - **Hackathon optimization:** prioritize the Backyard AI story: one real user, real |
| logged sessions, a precise small-model language job, deterministic training logic, a |
| live Gradio Space, demo video, and field notes. |
| - **Schema implementation:** use Pydantic models in a small `training_coach/` package. |
| - **`CheckIn` schema:** raw text, time available, energy level, sleep quality, optional |
| sleep hours, soreness/constraints, pain-or-injury flag, per-issue pain details, |
| mood/stress, and parser notes. `pain_or_injury` is only a coarse flag; specific |
| painful/problem areas live in `pain_issues`. |
| - **`PainIssue` schema:** each pain/problem issue represents one affected muscle, |
| severity, and notes. If two muscles are affected, store two `PainIssue` objects. If the |
| exact muscle is unclear, use `affected_muscle = null` and ask a follow-up. |
| - **`ParsedCheckIn` schema:** parser output wraps `CheckIn` with missing fields, |
| structured `follow_up_items`, display `follow_up_questions`, context signals, and |
| notes. Context signals capture adjacent correlations such as "ran a 10k yesterday" as |
| a reason to ask about energy or leg soreness. They are not engine decisions. |
| - **`Exercise` schema:** id, name, primary muscle group, secondary muscle groups, |
| compound flag, and rep range. Equipment is intentionally deferred. |
| - **Anatomical muscle enum:** use a practical anatomical `Muscle` enum for exercise |
| tagging, with primary and secondary muscles stored as enum values rather than free |
| text. This supports later pain/constraint filtering. |
| - **Set structure for MVP:** use classic straight sets only. Supersets, drop sets, rest |
| pause, and other advanced set types are deferred. |
| - **`SessionPlan` schema:** preserve exercise grouping and execution order. A |
| `SessionPlan` has date, structured `CheckIn`, ordered `PlannedExercise` entries, and |
| notes. Each `PlannedExercise` has exercise id, order, one or more `PrescribedSet` |
| entries, and notes. Each `PrescribedSet` stores set number, target rep range, optional |
| target load, and optional target RIR. |
| - **`SessionLog` schema:** mirror the planned exercise grouping. A `SessionLog` embeds |
| the planned session and stores ordered `LoggedExercise` entries. Each `LoggedSet` |
| stores set number, actual reps, actual load, optional RPE, optional rest seconds before |
| the set, and notes. |
| - **Parser model:** local MVP parser uses Ollama `qwen3:1.7B` by default for speed. |
| Earlier `qwen3:4b` runs passed the current parser acceptance fixtures after prompt |
| optimization and deterministic parser cleanup. |
| The parser may infer safe structured facts and possible context signals, but it must |
| not invent quantities or training actions. Pain information must use per-issue |
| `pain_issues`; exercise filtering is performed by the deterministic engine. |
| - **Parser behavior:** do not require one-shot perfection. The LLM extracts what it can |
| and proposes structured `follow_up_items`; deterministic cleanup removes duplicate, |
| already-answered, or unsupported follow-ups before display. Multiple question rounds |
| are acceptable before the engine builds a session. |
| - **Local parser runtime:** use Ollama/llama.cpp for local evaluation and development |
| because it is much faster on the Mac than local Transformers CPU/disk-offload. |
| `qwen3:1.7B` is the current local Ollama default for MVP speed. |
| - **Space parser runtime:** Hugging Face Spaces use a GGUF llama.cpp backend, |
| configured with `PARSER_BACKEND=llama_cpp`, |
| `LLAMA_CPP_MODEL_REPO=unsloth/Qwen3-1.7B-GGUF`, |
| `LLAMA_CPP_MODEL_FILE=Qwen3-1.7B-Q4_K_M.gguf`, `LLAMA_CPP_MAX_TOKENS=384`, |
| `LLAMA_CPP_N_CTX=2048`, and a Space-specific `LLAMA_CPP_N_THREADS`. This replaces the |
| slow CPU Transformers runtime. The Transformers backend remains only as an explicit |
| local experiment/fallback path and is not installed by the default requirements. |
| - **MVP training template:** use the supplied fixed 4-day exercise template for the |
| first engine slice. Preserve exercise grouping, execution order, set counts, rep |
| targets, and notes. For MVP simplicity, all exercise rests are normalized to 1 minute. |
| No adaptation, progression, or pain filtering is implied by the template itself. |
| - **Today's training day selection:** use next-day state from completed session logs. |
| The app should look at the last completed training day, suggest the next day in the |
| 1→2→3→4→1 rotation, and use that history later for double progression. This means |
| logging/persistence is part of the real MVP spine, not a cosmetic add-on. |
| - **MVP history depth:** use a minimal completed-session log for the MVP: completed |
| date, training day number, exercise id, set number, actual reps, actual load, and |
| optional RPE/notes. Richer session audit data is a post-MVP improvement. |
| - **Local history file:** local development stores completed MVP logs in |
| `data/completed_sessions.json`, which is ignored by git. |
| - **Performed-set logging UI:** do not use a dataframe/table for live workout logging. |
| After building today's session, the app shows one normal input row per prescribed set: |
| prefilled reps, load, optional RPE, and notes. Saving writes only rows with a load into |
| the minimal local history. |
| - **MVP pain filtering:** if `pain_or_injury` is `yes` and a `PainIssue` has a known |
| affected muscle, the engine removes exercises whose MVP muscle tags include that |
| muscle, including secondary involvement. It does not substitute replacement exercises |
| yet. |
| - **MVP time compression:** use `time_available_minutes` after pain filtering. At 60+ |
| minutes, run the full remaining plan. At 45-59 minutes, keep roughly 75% of sets. At |
| 30-44 minutes, keep roughly 60% of sets. Under 30 minutes, keep the first four |
| exercises and cap work at 8 sets. Within a compressed plan, preserve exercise order and |
| cut sets from later exercises first. |
| - **MVP readiness adaptation:** compute readiness from sleep quality, sleep duration, |
| energy, soreness text, and mood/stress using the guide weights. Apply readiness after |
| pain filtering and time compression. Very low readiness cuts sets about 50% and uses |
| target RIR 4. Low readiness cuts sets about 20% and uses target RIR 3. Normal/high |
| readiness keeps set count unchanged and uses target RIR 2. For MVP, low readiness is |
| `score < 3.0` so neutral/okay check-ins do not accidentally reduce the plan. |
| - **Coding agent model:** GPT-5.5 in Codex (current recommended default; 5.3-codex is |
| deprecated). |
|
|
| --- |
|
|
| ## Open — mine to decide (agent: ask, don't assume) |
|
|
| ### 1. Training methodology rules |
| The concrete IF/THEN training rules from my deep research — readiness→session mapping, |
| progression specifics, frequency, exercise ordering, time-compression priorities, |
| (later) periodization and deload triggers and volume targets. |
| **Status:** researched, not yet encoded. I will hand these over rule by rule. |
| **Agent:** do not invent these. Ask for the specific rule when the engine needs it. |
|
|
| ### 2. Remaining data schema |
| No remaining MVP data schema decisions are open right now. |
| **Status:** CLOSED for the current MVP schema. Reopen only when a new model need appears. |
|
|
| ### 3. Today's training day selection |
| Use next-day state from completed logs. |
| **Status:** CLOSED for MVP. |
|
|
| ### 4. Parser acceptance fixtures |
| The parser model is chosen and parser output is wired into the UI. Fixtures remain as |
| test coverage, not runtime behavior. |
| **Status:** CLOSED for MVP parser selection. |
|
|
| ### 5. Which stretch features to attempt, and in what order |
| Defaults in `PROJECT.md`, but the final call (and when to stop) is mine. |
| **Status:** OPEN. |
|
|
| --- |
|
|
| ## Notes / parking lot |
|
|
| - Modal (~€250 credits): reserved for a one-time fine-tune or batch job in the stretch |
| phase, not as a live inference backend. |
| - Proof-of-use for judging = my real logged sessions during the build window + a short |
| demo video showing a short/low-energy day reshaping a session. |
| - Future schema addition: exercise equipment, once equipment availability/substitution |
| becomes part of the app. |
| - MVP-relevant guide rules to encode next: review/refine readiness once real logs show |
| whether the score predicts performance. |
|
|