Skip to content

e1RM population policy v3

기계 기준은 docs/policies/e1rm/policy.json이다. 이 문서는 그 manifest의 의도와 사용 제한을 설명한다.

결정 요약

  • 정책 ID/버전은 lift-guild.e1rm@3.0.0, 곡선 ID/버전은 nuzzo-2024-general-inverse@1.0.0이다. 세트의 힘든 정도 입력이 5단계 버튼에서 **RPE 숫자 하나(1.0~10.0)**로 바뀌고 RIR을 10 − RPE로 직접 유도하므로 정책 major만 올리고 Nuzzo 곡선은 그대로 유지한다(이슈 #1237).
  • NRM은 실제로 수행한 정확한 1..20RM이고 e1RM은 별도 추정치다. e1RM은 measured PR state/event, PR 알림을 만들지 않는다.
  • e1RM은 stats_load_kg > 0인 정량 중량 세트에서 저장된 성공 반복이 있을 때 즉시 계산할 수 있다. 정량 지원 범위는 effective reps 1..20이다.
  • 0kg 또는 bodyweight-only 세트는 보편 %1RM kg 곡선의 입력이 아니므로 unavailable이다. 0kg e1RM을 만들어내지 않는다.
  • 완료된 1회 + RPE 101회 + RPE 미입력의 대표값은 실중량과 정확히 같다. 100%1RM = 1회는 논문값이 아니라 Lift Guild 제품 앵커다.
  • 지원 범위를 넘으면 외삽하지 않는다. 20회 경계를 보수 대표값으로 쓰고 low confidence, upper open으로 표시한다. 성공 반복이 0회인 실패 세트에는 대표 e1RM을 만들지 않고 시도 중량을 유한 상한 단서로만 보존한다.
  • 입력 원본 kg는 보존한다. 곡선 비율과 원시 projection은 충분한 정밀도를 유지하고, 공개 projection과 표시는 마지막에만 1kg half-up 한다.

원천과 파생 과정

일반곡선은 Nuzzo et al. (2024), Maximal Number of Repetitions at Percentages of the One Repetition Maximum: A Meta-Regression and Moderator Analysis of Sex, Age, Training Status, and Exercise의 general eccentric-concentric 표를 사용한다.

원천 표는 %1RM, 평균 최대 반복 수, 개인 간 SD의 point estimate만 담는다. 논문 표의 평균·SD 모수에 대한 95% CI는 런타임 계산에 사용하지 않는다.

파생 절차는 다음과 같다.

  1. 제품 앵커 (100%1RM, 1 repetition, SD 0)를 추가한다.
  2. 각 공개 %1RM knot에서 mean ± 1.2815515655446004 × between-person SD로 대칭 80% 반복수 reference를 만든다.
  3. low/center/high 반복수 곡선을 각각 arbitrary numeric effective reps에 대해 직접 역선형보간한다.
  4. 파생된 %1RMload_pct_reference_low, load_pct_reference_center, load_pct_reference_high로 기록한다.

정수 1..20 표는 conformance fixture일 뿐 런타임 knot가 아니다. 예를 들어 RIR 3.5처럼 effective reps가 소수이면 반드시 원천 knot를 직접 역보간한다. 정수 표를 다시 보간하면 이중 보간 오차가 생긴다.

이 band의 정식 이름은 inverted population reference band다. %1RM | reps의 조건부 분위수나 개인화 모델이 아니며 신뢰구간이 아니다. Epley·Brzycki 같은 공식 간 차이도 uncertainty band로 취급하지 않는다.

Attribution/change notice: Derived from the general eccentric-concentric repetitions-to-failure predictions in Nuzzo et al. (2024), CC BY 4.0. Lift Guild added a 100%1RM=1-repetition domain anchor, formed an approximate symmetric 80% individual reference band from the published point mean and between-person SD, and monotonically inverted the curves by piecewise-linear interpolation. These inverse bands are application-derived and were not reported by the authors.

계산

대표 effective reps는 다음과 같다.

text
effective_reps = completed_reps + representative_rir
e1rm_center = load_kg / (load_pct_reference_center / 100)
population_reference_lower = load_kg / (load_pct_reference_high / 100)
population_reference_upper = load_kg / (load_pct_reference_low / 100)

population_reference_lower/upper는 입력 불확실성을 합친 total interval이 아니다. RIR 범위, open-ended 입력, 체감 미입력 상태는 별도 metadata로 보존한다. 특히 체감 미입력은 RIR0 대표값만 제공하고 finite upper estimate를 제공하지 않는다.

Golden cases:

입력effective repspopulation lower / center / upper
210kg × 1, RIR01210 / 210 / 210kg
150kg × 10, RIR010176.63 / 188.58 / 209.70kg
150kg × 10, RIR313187.59 / 203.45 / 238.70kg

RPE와 confidence

세션 의도는 training | rm_test로 원본에 저장하며 기본값은 training이다. rm_test는 측정 맥락과 목표 반복을 명시적으로 보존하기 위한 값이지, e1RM 공식을 바꾸는 스위치가 아니다. 성공·부분 실패의 계산 의미는 아래 set_result와 실제 완료 반복 수가 결정한다.

세트의 힘든 정도 입력은 RPE 숫자 하나다 — exercise_sets.perceived_rpe, numeric(3,1), 1.0~10.0, 소수 1자리. v1·v2의 5단계 wire contract(level 1..5, lift-guild.perceived-effort@1.0.0)는 v3에서 퇴역했고, 남아 있던 5단계 값은 컷오버 때 RPE = level + 5로 한 번 변환됐다. 기록 화면의 6·7·8·9·10 버튼은 이 숫자를 빠르게 넣는 단축키일 뿐 별도의 카테고리가 아니다(오너 지시 2026-09-04).

RIR은 RPE에서 직접 유도한다: RIR = 10 − RPE. 반값(8.5 → RIR 1.5)은 그대로 effective reps에 들어가며 원천 knot를 직접 역보간한다.

입력대표 RIRRIR 범위kindconfidence
RPE ≥ 6.0 (닫힌 구간)10 − RPE정확히 10 − RPEpoint/rangemedium (지원 범위 안)
RPE < 6.0 (열린 구간, 웜업·가벼운 세트)10 − RPE10 − RPE 이상, 상한 없음conditional_openlow
RPE 미입력00 이상, 상한 없음conditional_openlow
완료 1회 @ RPE 10.000pointhigh
rep_failure0 (관측)0RPE 무시아래 규칙
  • high: completed 1 rep + RPE 10.0의 exact product anchor만 해당한다.
  • medium: 지원 범위 안의 닫힌 RIR(RPE ≥ 6.0)이다. high 조건은 제외한다.
  • low: RPE 미입력, RPE < 6.0의 open range, 지원 범위 밖, rep_failure(0회 완료)다.
  • population reference band 폭과 confidence 등급은 다른 개념이다.
  • 기존 legacy difficulty(2026-06~07의 1~10 숫자)는 런타임에 RIR로 자동 재해석하지 않는다. v3 컷오버에서 화면이 보여주던 대로 한 번 변환(3 이하→7, 6 이하→8, 8 이하→9, 그 밖→10)한 뒤 컬럼을 삭제했고, 원값은 세트의 raw_payload.legacy_difficulty에 남겼다.

set_resultcompleted | rep_failure만 저장한다. aborted는 저장하지 않는다. 실패는 completed_repstarget_reps를 분리하며, 0 completed reps는 rep_failure에서만 허용한다.

rep_failure는 실제 완료 반복 수에 따라 두 갈래로 처리한다.

  • completed_reps >= 1: 다음 반복 실패로 RIR 0이 관측된 것으로 본다. 저장된 체감은 계산에 사용하지 않고, 실제 완료 반복 수로 Nuzzo 곡선을 조회해 대표 e1RM을 만든다. 지원 범위 안에서는 medium / range이며 세션 투표에 참여한다. 20회를 넘으면 기존 경계 정책대로 low / conditional_open이다.
  • completed_reps = 0: 대표 e1RM과 투표 자격은 없고 low / censored_high로 남긴다. 이 경우 attempted stats_load_kg실제 1RM < 시도 중량이라는 유한 상한 단서다.

예를 들어 target_reps=5, completed_reps=4인 실패 세트는 5RM이 아니라 수행한 중량의 4RM measured NRM 후보인 동시에, 4회 + 관측 RIR 0 기반 e1RM 후보다. 실제 완료 반복이 1..20일 때만 해당 반복수 NRM projection에 포함하며, completed_reps=0이면 measured NRM은 없다. 추정 e1RM은 계속 measured PR state/event와 분리한다.

집계, 그래프, stale

세트 후보는 confidence high→medium→low, 같은 confidence 안에서는 관측된 반복 실패→주관적/미입력 체감, set type top→main→warmup, 지원 effective reps 오름차순, 대표 e1RM 내림차순, position/id 순으로 정렬한다. 세션마다 정보량 상위 3개만 고르고 confidence weight high=4, medium=2, low=1의 weighted median으로 한 표를 만든다. 날짜는 세션 표의 weighted median 한 점을 선택한다. 정확히 중앙이 갈리면 낮은 값을 선택한다.

medium/high가 하나라도 있으면 low evidence는 제외한다. low만 있을 때 비교하는 prior trusted 값은 가장 최근에 채택된 medium/high daily point다. 아직 trusted point가 없으면 low끼리는 상승·하락할 수 있다. trusted point가 생긴 뒤에는 low 후보가 그 값 이상일 때만 채택되며, 채택된 low 값 자체가 trusted floor를 덮어쓰지 않는다. 이후 새 medium/high point가 들어오면 상승·하락과 관계없이 trusted floor를 그 값으로 재설정한다. 그래프에는 선택된 daily point와 그 point의 population reference band만 노출한다.

90일이 지나면 값을 자동 감쇠하지 않고 stale로만 표시한다. projection 작업은 비동기·멱등이어야 하며 generation guard를 통과한 최신 결과만 게시한다.

세트 강도 분모는 세션 시작 전에 존재한 reference만 사용한다. 현재 세션 e1RM은 즉시 보이지만 자기 세션의 분모를 갱신하지 않는다. 첫 세션은 reference intensity가 null이고 다음 세션부터 강도를 표시한다.

stimulus classifier는 별도 lift-guild.stimulus-classifier@1.0.0 derivative다. pre-session reference intensity가 없으면 분류하지 않으며 v1 경계는 strength >=85%, hypertrophy >=65% and <85%, endurance <65%다.

버전과 breaking change

원천 표/hash, 제품 앵커, reference band, 역보간, eligibility, RPE→RIR/결측 정책, 지원 경계, 반올림, reference timing, 집계, stale, projection 실행, stimulus classifier, NRM 분리는 breaking contract다.

이 중 하나라도 계산이나 의미를 바꾸면:

  1. 정책 또는 곡선 major version을 올린다.
  2. 기존 버전 artifact를 보존한다.
  3. changelog.jsonCHANGELOG.md에 새 entry를 추가한다.
  4. 새 fingerprint와 SHA-256을 기록한다.
  5. 모든 e1RM projection을 전량 replay한다.

검증과 재생성:

bash
node scripts/generate-universal-rep-curve.mjs --check
node scripts/generate-universal-rep-curve.mjs --write
npm run check:policies