Skip to content

FEAT - Preserve zero-weight muscle mappings without counting effective volume #345

Description

@EmilZapata

What problem does this solve?

This is a follow-up to #327 and PR #333. That work introduced planned versus completed weekly muscle volume; this proposal improves the underlying muscle-weight metadata by preserving explicit zero-credit relationships without changing the current 0.4 secondary-muscle fallback.

openGym currently assigns 1.0 to primary muscles and 0.4 to every secondary muscle. That remains a useful fallback, but some exercise metadata includes muscles that should not receive effective hypertrophy-set credit. They may be anatomical stabilizers, antagonists, or inherited catalogue associations rather than meaningful contributors to the training stimulus.

Removing those muscles from metadata is not ideal because it loses an explicit, reviewable decision. The data should be able to say that a muscle remains associated with an exercise while contributing zero effective sets:

muscleWeights: {
  chest: 1,
  triceps: 0.4,
  biceps: 0,
}

Today, musclesOf() only retains explicit weights greater than zero:

if (Number.isFinite(weight) && weight > 0) snapshot[slug] = weight

As a result, an explicit zero cannot survive the effective-weight resolution or exerciseMuscleSnapshot(). It is therefore impossible to distinguish between a deliberately reviewed zero, an exercise-muscle pair that has not been reviewed, and metadata that was accidentally removed.

There is also an important behavioral constraint: returning zero-valued keys directly from musclesOf() would be unsafe because consumers such as strengthOf() currently treat every returned key as recently trained without checking its numeric value.

The global 0.4 value is not the main issue here. Current evidence does not justify replacing it with another universal coefficient. The immediate improvement is to preserve explicit zeros for reviewed exercise-muscle relationships while ensuring they never contribute to effective training calculations.

Proposed approach

1. Preserve explicit zero-weight overrides

Use the existing owner-approved correction layer in frontend/src/lib/exercise-muscle-batch-1.js rather than modifying the generated exercises-data.js catalogue.

Conceptually:

export const USER_EXERCISE_MUSCLE_OVERRIDES = Object.freeze({
  '0150': {
    muscleWeightOverrides: {
      triceps: 0,
    },
  },
  '0606': {
    muscleWeightOverrides: {
      chest: 0,
      triceps: 0,
    },
  },
})

The exact field name is open to maintainer preference. The important contract is that zero is a deliberate persisted value, not the absence of metadata.

2. Separate complete metadata from effective stimulus

Introduce a zero-aware resolver, conceptually muscleWeightsOf(ex), that returns the complete reviewed weight map, including explicit zeros.

Keep musclesOf(ex) as the effective-stimulus view and return only weights greater than zero:

export function musclesOf(ex) {
  return Object.fromEntries(
    Object.entries(muscleWeightsOf(ex))
      .filter(([, weight]) => weight > 0)
  )
}

This keeps current volume, fatigue, recovery, strength, and body-map consumers safe without requiring every caller to understand zero-weight metadata.

3. Preserve zero values in snapshots

exerciseMuscleSnapshot() should store the complete map from the zero-aware resolver rather than the positive-only effective map. This preserves reviewed zero values for custom exercises and historical entries even if the catalogue entry is later changed or deleted.

4. Preserve taxonomy separately

muscleGroupsOf() should continue to expose anatomical/taxonomic membership independently from effective-set contribution. A muscle with weight 0 may remain inspectable and auditable, but it must not shade the body map or contribute to effective volume.

Initial reviewed candidates

The first small correction batch could assign explicit zero effective-set credit to mappings that currently appear to overstate meaningful hypertrophy stimulus:

  • Triceps in pull-ups and lat pulldowns.
  • Chest and triceps in T-bar rows.
  • Biceps in chest presses.
  • Hamstrings in calf presses.
  • Hamstrings in seated hip abduction.
  • Calves in hack squats and leg presses when no dynamic plantar flexion occurs.
  • Biceps in pec-deck or machine-fly movements.
  • Deltoids in direct triceps extensions when their role is only stabilization.

Each correction should remain an explicit override so it can be independently reviewed or revised later.

Acceptance criteria

  • Explicit exercise-muscle weights from 0 through 1 are accepted.
  • Explicit zero values remain present in catalogue metadata.
  • Custom-exercise and historical snapshots preserve explicit zero values.
  • A zero-weight muscle adds no planned or completed effective volume.
  • A zero-weight muscle adds no fatigue or recovery stimulus.
  • A zero-weight muscle does not update retained strength or the last-trained timestamp.
  • A zero-weight muscle adds no body-map intensity.
  • Anatomical/taxonomic membership remains available through the appropriate metadata helper.
  • Exercises without explicit overrides retain the current 1.0 primary and 0.4 secondary behavior.
  • Existing saved workouts and snapshots remain compatible.
  • Focused tests cover metadata resolution, snapshots, volume, recovery, and strength behavior.

Expected files

frontend/src/lib/exercise-muscle-batch-1.js
frontend/src/lib/muscles.js
frontend/src/lib/muscles.test.js
frontend/src/lib/recovery.test.js
frontend/src/lib/strength-exercises.test.js

frontend/src/lib/exercises-data.js should remain unchanged because it is generated. Plan.jsx and Stats.jsx should not require direct changes because they already consume the shared load helpers.

Out of scope

  • Replacing the global 0.4 fallback with 0.5 or another universal value.
  • Recalibrating all catalogue exercises in one change.
  • Presenting exercise-muscle weights as exact physiological equivalences.
  • Removing a muscle from metadata solely because its effective weight is zero.

Evidence context

The best current aggregate evidence found that counting indirect sets as 0.5 fit hypertrophy outcomes better than counting them as 0 or 1. However, only those three models were compared, and the authors explicitly describe fractional counting as a heuristic rather than a universal physiological coefficient. This proposal therefore keeps the existing fallback and focuses only on explicit, reviewable zero-credit relationships.

If this direction makes sense, we would be happy to implement it and open a focused PR.

Dependencies

  • This doesn't require adding a new dependency

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions