When a Workout Becomes a Next Prescription

In openGym, a routine is not the same thing as a workout, and a workout is not the same thing as the next recommendation. This chapter follows the chain between those three states: what the plan intends, what the person actually logs, and what the application derives when the next session begins. The value of that distinction is practical. It lets a reader see why a progression result can be explained, corrected, or constrained instead of emerging from an invisible counter.

From Plan Intent to Historical Evidence

A routine is a statement of intent. It can say that an exercise belongs on a particular day, how many sets to perform, which rep target or time target to use, and which progression policy should apply. It does not prove that the person completed those sets. A workout is the record of the attempt: which entries were present, which sets were marked complete, what weight, reps, duration, or effort was logged, and which routine context shaped the session.

That difference begins when openGym builds a planned session. The application reads the routine’s configuration and the exercise’s history, chooses a policy, and applies the policy while constructing the entries that will appear on the workout screen. The session therefore opens with a prescription that can already differ from the routine’s stored starting weight or rep target. The difference is not an accidental mutation of the plan. The session keeps the plan’s intended values separately from the current target that progression selected.

This separation solves a common ambiguity. Suppose a routine originally asks for three sets of eight at a certain load, and the progression rule moves the current target upward after earlier successful sessions. The workout needs to know both facts: what the routine asked for and what the policy selected today. Later, if the user edits the routine to a different number of sets or reps, the application can tell that the old session was built from an earlier plan. It does not mistake an old prescription for evidence about the new one.

The same principle applies to a routine that has never trained an exercise. openGym can use the exercise’s configured target as a starting point, but it cannot honestly claim that the person has already established a working load. The first session becomes a baseline. A copied or newly introduced routine can use broader exercise history when it has no routine-specific history, but the routine’s own line takes priority once it exists. That keeps a heavy and light day from being treated as one undifferentiated progression track merely because both contain the same movement.

When a session ends, the application reduces the live interaction to a completed workout. Live-only bookkeeping is removed. The durable record retains the logged sets, the target that was used, the routine identity, the planned values needed to interpret later edits, and relevant notes or exclusions. An unfinished row without completed work does not become a historical entry simply because it was visible on the screen. A completed workout is therefore not a screenshot of the interface; it is a cleaned record of what happened.

The progression engine then reads that record rather than maintaining a second private count of successes. Its basic grading rule is deliberately concrete. A completed set that reaches at least its target reps counts as successful; a checked set below target is a miss; an unchecked set is also a miss because it was not performed; and a session with fewer sets than prescribed is incomplete. Warm-up rows are treated as preparation rather than work. Extra sets can remain part of the workout’s volume and history, but they do not silently turn a bonus effort into a new prescription or allow one difficult bonus set to make an otherwise successful planned session look like a failure.

That last choice is a product judgment about what the plan is allowed to learn. The planned sets are the evidence used to decide whether the prescription was met. The rest of the workout remains valuable for history, volume, and records, but it does not automatically rewrite the policy’s contract. This gives the user room to do extra work without making every deviation change the next session.

The result can be described as a loop:

sequenceDiagram participant R as Routine intent participant B as Session builder participant A as Athlete participant H as History reader participant P as Progression policy R->>B: Provide sets, reps, mode, and policy B->>H: Read relevant routine history H-->>B: Return prior completed sessions B->>P: Ask for today's prescription P-->>B: Return target and explanation B-->>A: Show planned rows and current target A->>B: Log completed or missed work B->>H: Persist completed workout evidence H->>P: Grade planned work for next session P-->>B: Derive next target and reason P-->>B: Branch for bodyweight or assisted work when load is not ordinary

The loop is important because openGym’s ownership model depends on keeping the record authoritative. A recommendation can be regenerated. The completed set is the event that must be preserved. If a person later fixes a mistyped load or changes a routine, the application can derive a different next target without pretending that the original log never existed.

Policies Are Bounded Decisions, Not Generic Fitness Advice

The shipped policies are different ways of answering the same question: given the last relevant evidence, what should change next, and under what condition should it hold or back off? “Off” means the targets stay where the user set them. Linear progression increases the load when every planned rep is achieved and can deload after repeated misses. Greyskull uses a different pattern, including a final set taken to failure and a stronger response to that result. Double progression keeps the load while the person climbs through a rep range, then increases the load and returns the reps toward the lower end. Time-based progression advances a duration when every planned hold is completed.

The important point is not the names. It is that the policy is selected explicitly and its output is accompanied by a reason. A clean session may produce an explanation such as “every rep in every set was completed, so the target goes up.” A short session may produce “same target again.” Repeated misses may produce a deload explanation. The language makes the transition inspectable: the person can compare the recommendation with the logged evidence instead of accepting a mysterious number because the interface displayed it.

The policies also operate on an exercise-specific load step. A small lift and a lower-body lift do not necessarily use the same increment, and a routine can provide an override. For some loaded rep work, the deload path uses an estimated-strength target and searches for a bounded load-and-rep pair that fits the exercise’s usable grid. That is a concrete engineering choice: a deload should land on a weight the person can actually load, not merely on an abstract percentage that produces an awkward or unavailable number.

These rules are deliberately narrower than a complete theory of training. They decide how openGym translates its own stored evidence into a next screen. They do not establish that one policy is optimal for every athlete, nor do they diagnose injury, fatigue, or readiness. The application’s documentation and code support a deterministic product behavior; they do not turn that behavior into medical guidance.

The edge cases reveal why a generic “add weight after success” rule would be misleading. A push-up or another bodyweight movement may be logged with zero external load even when the person worked hard. Treating zero as a failed load measurement would make the application propose adding an arbitrary weight to a movement whose ordinary progression is reps first. openGym therefore lets bodyweight work climb through reps, and when a rep ceiling is reached, through additional sets up to a bounded point. Once further sets stop being a useful answer, the system holds and explains that load or a harder variation becomes a human decision rather than an automatic policy outcome.

Unilateral work creates a different problem. If the stored total represents both sides, an increase of one rep would leave the two limbs out of step. The model therefore advances per-side targets in even totals. The person logs the work in the application’s chosen total convention, while the progression rule preserves the meaning of that total. This is not a cosmetic display preference. If the total were interpreted sometimes as one side and sometimes as both, the same number would change meaning from one session to the next.

Assisted machines reverse the direction of ordinary load progression. On an assistance stack, less assistance is harder. A clean session should move toward less help, while a stall may require more assistance. The underlying ideas—recognize a hit, count a stall, change by a step, explain why—can remain shared, but the direction of “harder” cannot be assumed from the sign of the number. Keeping that distinction in the exercise semantics prevents a superficially reasonable rule from rewarding a person with an easier setting.

Timed work is also not just rep work with a different label. A hold has a duration target, so the success condition is that every planned hold reaches the required time. Its progression changes seconds rather than reps or load. Cardio has its own mode as well. openGym’s model makes the logging mode explicit enough that the progression engine, history reader, and display can avoid interpreting a duration or speed as if it were a weight-and-reps set.

This is why the exercise model and the ownership model meet in the same place. A person owns a record only if the application preserves the meaning of the record. “Zero weight” must be distinguishable from “weight not entered.” “Sixteen reps” must retain its per-side convention. “Twenty seconds” must not be read as twenty repetitions. A stored number without its domain context is not reliable evidence; it is merely a value waiting to be misinterpreted.

The pure-function design reinforces that discipline. The progression code is kept apart from the interface and tested as domain logic. Its output is derived from the state it receives, and the finished workout is not rewritten merely because a future policy changes. That makes a policy change consequential but understandable: the application may calculate a different next target from the same corrected history, while the record of what happened remains the record of what happened.

A useful way to test the mechanism is to compare three sessions that look similar on the screen but mean different things to the engine. In the first, the person completes every planned set at the required reps. The policy may increase the next load or move the target forward, depending on its rules. In the second, the person completes the first sets but leaves the last one unchecked. The visible workout may contain substantial work, yet the planned prescription was not completed, so the next target cannot advance as if it had been. In the third, the person finishes the plan and adds a difficult bonus set. That bonus set belongs in the history and may matter to volume or records, but it does not by itself rewrite the planned contract. The distinction keeps the recommendation tied to evidence that the policy knows how to interpret.

A plan edit creates another important boundary. If a person changes three sets of eight to four sets of six, the previous session was not a failure against the new plan; it was performed against the old one. openGym records the planned values used to build the session so a later read can recognize that change. The next prescription can begin from the revised plan instead of carrying a stale miss streak into it. This prevents a routine edit from being misread as a training collapse and prevents the old target from controlling a new intent.

The same logic protects deliberate exceptions. A user may mark a session or exercise as excluded from progression because it was a rehab day or an unusual circumstance. The workout remains part of the history, but it does not become the baseline for the next ordinary prescription. This is another example of why the record needs context. The question is not simply “was there a number in the file?” It is “what role was this entry allowed to play when the application derived the next decision?”

These distinctions also explain why the application keeps a policy result alongside a reason rather than showing only the resulting number. A load that stays the same can mean several different things: the last session missed the target and should be repeated, the plan changed and progression restarted, no load was logged and the person must establish one, or the exercise is bodyweight work and its progress is being expressed in reps. The number alone cannot tell those cases apart. A reason is a compact statement of which transition occurred and what evidence triggered it.

For a user, that makes correction possible at the right level. If the recorded set is wrong, correct the set. If the routine target is wrong, edit the routine. If the policy is not appropriate for the movement, change the policy. A system that stores only the final weight would make these interventions indistinguishable; a system that preserves intent, evidence, and derivation can respond to the correction without erasing the history that led to the original result.

The ownership benefit is therefore more specific than “the user can inspect the files.” openGym gives the user a way to inspect the reasoning that connects the files to the next action. The plan supplies intent, the completed workout supplies evidence, the policy supplies a bounded transformation, and the reason describes the result. The next question is what happens when the evidence itself needs correction: whether a saved workout can be edited without breaking the relationship between history, progression, and the derived views built on top of it.

References