trainlog/catalog/session-generation-policy-v1.json

187 lines
15 KiB
JSON

{
"format": "trainlog-session-generation-policy-v1",
"version": 1,
"policy_id": "session_generator_v1",
"status": "canonical_frozen",
"scientific_review_date": "2026-09-09",
"confidence": "moderate",
"scope": "Editable single-session resistance-training suggestions for adults; separate from frozen read-only TRAINING_KNOWLEDGE_V1.",
"numeric_rule_status": "All exact defaults, windows, thresholds, scores and caps are practical engineering conventions, not validated individualized prescriptions.",
"source_refs": ["acsm_2009", "acsm_2026_generator", "currier_2023", "grgic_2022", "kassiano_2022", "moran_navarro_2017_generator", "singer_2024_generator", "vieira_2022"],
"additional_references": [
{
"ref_id": "acsm_2026_generator",
"title": "American College of Sports Medicine Position Stand. Resistance Training Prescription for Muscle Function, Hypertrophy, and Physical Performance in Healthy Adults: An Overview of Reviews",
"authors_or_organization": "Currier BS and colleagues; American College of Sports Medicine",
"year": 2026,
"pmid": "41843416",
"doi": "10.1249/MSS.0000000000003897",
"url": "https://pubmed.ncbi.nlm.nih.gov/41843416/",
"type": "intervention_evidence",
"notes": "Overview of 137 systematic reviews: resistance training improves multiple outcomes; heavier loads favor strength, higher weekly volume favors hypertrophy; many other prescription variables do not consistently alter outcomes.",
"limitations": "Healthy adults and multiweek interventions, not validation of this one-session algorithm; searches current to October 2024. Does not validate an unknown MAX as 1RM.",
"accessed_on": "2026-09-09"
},
{
"ref_id": "moran_navarro_2017_generator",
"title": "Time course of recovery following resistance training leading or not to failure",
"authors_or_organization": "Moran-Navarro R and colleagues",
"year": 2017,
"pmid": "28965198",
"doi": "10.1007/s00421-017-3725-7",
"url": "https://pubmed.ncbi.nlm.nih.gov/28965198/",
"type": "intervention_evidence",
"notes": "Failure and nonfailure protocols produced different recovery courses even with matched total repetition volume.",
"limitations": "Ten trained men, bench press and squat, selected acute markers; cannot calibrate body-zone recovery from Trainlog history.",
"accessed_on": "2026-09-09"
},
{
"ref_id": "singer_2024_generator",
"title": "Give it a rest: a systematic review with Bayesian meta-analysis on the effect of inter-set rest interval duration on muscle hypertrophy",
"authors_or_organization": "Singer A and colleagues",
"year": 2024,
"pmid": "39205815",
"doi": "10.3389/fspor.2024.1429789",
"url": "https://pubmed.ncbi.nlm.nih.gov/39205815/",
"type": "intervention_evidence",
"notes": "Nine studies suggest a small hypertrophy advantage to rests exceeding 60 seconds, with broad uncertainty and little detected difference above 90 seconds.",
"limitations": "Small heterogeneous evidence base; does not establish exactly 120 seconds as universally optimal.",
"accessed_on": "2026-09-09"
}
],
"goals": {
"general": {"sets": 2, "repetitions": 10, "rest_seconds": 90, "sets_range": [1, 3], "repetitions_range": [8, 12], "rest_seconds_range": [60, 120]},
"strength": {"sets": 3, "repetitions": 6, "rest_seconds": 180, "sets_range": [2, 3], "repetitions_range": [5, 8], "rest_seconds_range": [180, 300]},
"hypertrophy": {"sets": 3, "repetitions": 10, "rest_seconds": 120, "sets_range": [2, 3], "repetitions_range": [8, 12], "rest_seconds_range": [90, 180]},
"endurance": {"sets": 2, "repetitions": 16, "rest_seconds": 60, "sets_range": [1, 3], "repetitions_range": [15, 20], "rest_seconds_range": [45, 90]}
},
"goal_range_interpretation": "Inclusive broad editable guidance, not RM zones, validated optimal intervals or hard physiological limits; default generation uses the single default values unless explicitly overridden, and then recomputes duration and load qualification.",
"zone_expansion": {
"full_body": ["chest", "back", "shoulders", "arms", "core", "glutes", "thighs", "calves"],
"upper_body": ["chest", "back", "shoulders", "arms"],
"chest": ["chest"],
"back": ["back"],
"shoulders": ["shoulders"],
"arms": ["arms"],
"core": ["core"],
"lower_body": ["glutes", "thighs", "calves"],
"glutes": ["glutes"],
"thighs": ["thighs"],
"calves": ["calves"]
},
"eligibility": {
"recording_mode": "SETS",
"tracking_mode": "REPS",
"knowledge_resolution": "resolved_family_variant_limited",
"allowed_confidence": ["high", "moderate"],
"require_runtime_exercise_id": true,
"require_explicit_equipment_compatibility": true,
"unknown_conditional_and_unlinked_capabilities": "exclude_with_reason",
"scientific_zone_role": "primary_or_secondary",
"persisted_zone_disagreement": "explain_without_mutation",
"equipment_choice": "Among available compatible contexts prefer newest qualifying working-load anchor, then bytewise equipment_id; select one context per exercise. MAX does not select a context."
},
"load": {
"lookback_seconds": 2419200,
"window": "0 <= reference_instant - occurrence_instant <= lookback_seconds",
"required_context": ["exact_exercise_id", "non_null_exact_equipment_id", "external_load_semantics", "no_known_execution_context_conflict"],
"priority": ["recent_repeated_performed_sets", "absent"],
"working_rule": "In the newest qualifying completed occurrence require at least proposed sets actual rows with positive finite weight and actual repetitions >= proposed repetitions. Reuse the minimum weight among those qualifying rows without increase. An occurrence with fewer qualifying rows cannot establish repeated-dose support.",
"actual_load_mode_compatibility": "Exact known scientifically compatible external equipment is required. Occurrence mode external qualifies; mode none qualifies only for actual-only shape with all targets absent and rest_seconds=0. This applies independently of exchange version and never rewrites stored mode. Explicit assistance or conflicting/unknown equipment never qualifies.",
"planned_load_mode": "Follow normal desktop plan invariants: absent numeric target weight means load_mode none; present target weight means external or assistance. Keep selected equipment resistance semantics separate from planning mode. Generator assistance numeric weight remains absent.",
"working_confidence": "uncertain",
"working_meaning": "Observed repetition completion only; effort, failure, technique, range and physiological readiness are not established. Warmup rows cannot be reliably separated.",
"max_rule": "No numeric prescription from explicit MAX. An occurrence-owned maximum without repetition count does not establish 1RM or any goal-specific repetition capacity. A compatible explicit MAX may be exposed only as context with explicit_max_present_no_numeric_prescription; target weight remains absent unless repeated actual-set evidence qualifies.",
"max_confidence": "uncertain",
"max_only_does_not_create_performed_sets": true,
"assistance": "omit_numeric_load_and_explain_assistance",
"bodyweight_or_unknown_semantics": "omit_numeric_load",
"machine_increment": "not_known; retain a qualifying observed actual load unchanged as an indicative editable value; invent no increment and perform no automatic rounding",
"progression": "none"
},
"exposure": {
"short_window_seconds": 86400,
"long_window_seconds": 259200,
"window": "0 <= reference_instant - occurrence_instant < window_seconds",
"timestamp_policy": "reuse_exact_TRAINING_KNOWLEDGE_V1_instant_comparison",
"invalid_timestamp": "Invalid reference input fails request validation; any invalid stored timestamp encountered by the required history reader fails analysis explicitly under the existing temporal contract. Return the specific error and no complete exposure or generation result; never skip malformed timestamps as outside-window data.",
"counted_rows": "completed-history actual SETS+REPS rows with repetitions > 0; weight may be absent; deduplicate by occurrence/set identity",
"excluded": ["draft", "target_only", "zero_performed_sets", "explicit_max_only", "continuous_activity", "future_occurrence"],
"zone_source": "resolved_scientific_interpretation; unknown history marked unclassified, never converted from names",
"primary_secondary": "separate integer counts per zone; one set counts once in each explicitly supported role; never sum role counts as equivalent effective sets",
"requested_zone_aggregation": "Expand the requested zone, then evaluate each distinct actual row once: primary if its scientific primary is in the expansion; otherwise secondary if any scientific secondary is in the expansion; otherwise neither. Primary wins over all secondary descendant matches. Do not add leaf counters to form parent counters.",
"summary_consistency": "For each 24h/72h summary, set_count=primary_count+secondary_count is the deduplicated number of recorded rows, not effective physiological sets; session_count is distinct matching session IDs; pattern_ids is the sorted distinct union from exactly those matching rows. Last exposure is the newest matching nonfuture actual-row occurrence across the complete queried history, independently of the windows, with its source session/occurrence IDs and scientific pattern IDs. Unknown or incomplete history cannot produce a complete summary claim.",
"recent_primary_sets_24h_threshold": 1,
"recent_secondary_sets_24h_threshold": 3,
"repeated_primary_sets_72h_threshold": 6,
"repeated_secondary_sets_72h_threshold": 12,
"status": "recent_exposure if either short threshold; repeated_exposure if either long threshold; both flags may coexist; otherwise no_threshold_observed, never recovered",
"warning_levels": {
"none": "No primary or secondary exposure threshold met in a successfully completed analysis; does not mean recovered or safe.",
"notice": "At least one secondary threshold met and no primary threshold met.",
"warning": "At least one primary threshold met, regardless of secondary flags; informational and nonblocking."
},
"unknown_history": "insufficient_information; zero observed classified sets does not prove no activity",
"user_continuation": "always_available; flags are informational, not a medical restriction or biological recovery estimate"
},
"selection": {
"max_exercises": 6,
"max_per_exact_pattern": 1,
"duplicate_exercise": "forbidden",
"pattern_overlap": "exclude candidate if any of its exact pattern IDs is already selected",
"optional_preferences": {
"preferred_exercise_ids": "soft preference on exact UUID; duplicate requested IDs have no extra effect",
"excluded_exercise_ids": "hard exclusion on exact UUID; wins over preferred",
"excluded_pattern_ids": "hard exclusion if any scientific pattern ID intersects the supplied known pattern IDs",
"precedence": "Availability, scientific eligibility, explicit exclusions, duplicate/diversity limits and duration fit are applied before coverage priority and score. Preference never creates an unavailable or unreviewed candidate.",
"unknown_ids": "Unknown exercise IDs yield no candidate and are reported as unavailable/unmatched preferences or exclusions; unknown pattern IDs fail request validation."
},
"recency": {
"same_exercise_window_seconds": 259200,
"same_pattern_window_seconds": 604800,
"window": "0 <= reference_instant - occurrence_instant < window_seconds",
"evidence": "At least one positive-repetition actual row in completed history; same exercise means exact UUID across equipment contexts, same pattern means nonempty intersection of resolved scientific pattern IDs. Count neither targets nor MAX-only occurrences; identity/pattern selection recency never authorizes cross-equipment load transfer.",
"application": "Apply each boolean recency penalty once, additively to existing zone penalties, with no cooldown exclusion. Exact boundary ages are outside their respective windows."
},
"score": {
"requested_primary_zone": 100,
"requested_secondary_zone_only": 60,
"new_primary_zone": 20,
"new_pattern": 30,
"qualifying_working_load_history": 5,
"preferred_exercise": 15,
"recent_same_exercise": -25,
"recent_same_pattern": -15,
"recent_primary_threshold_on_candidate_primary": -30,
"recent_secondary_threshold_on_candidate_primary": -10,
"repeated_primary_threshold_on_candidate_primary": -20,
"repeated_secondary_threshold_on_candidate_primary": -10,
"any_exposure_flag_on_candidate_secondary_zones": -10
},
"algorithm": "Greedy highest total score among eligible candidates fitting remaining duration; recompute coverage bonuses after each selection; tie by bytewise exercise_id then equipment_id. Each boolean score applies at most once. Primary and secondary match base scores are mutually exclusive.",
"group_coverage": "For full_body prefer an as-yet unrepresented upper/lower/core region before repeating a represented region whenever a fitting candidate exists. For upper_body prefer one push and one pull before further upper-body patterns whenever available. For lower_body prefer knee extension/hip extension and knee flexion before other functions whenever available. Apply these as candidate-pool priorities before numeric score.",
"upper_push_patterns": ["horizontal_push", "vertical_push"],
"upper_pull_patterns": ["horizontal_pull", "vertical_pull"],
"lower_extension_patterns": ["knee_dominant", "hip_dominant", "single_joint_knee_extension"],
"lower_flexion_patterns": ["single_joint_knee_flexion"],
"coverage_shortage": "report actual missing patterns/regions; never invent exercises or fill time with redundant variants"
},
"duration": {
"presets_minutes": [30, 45, 60],
"custom_min_minutes": 10,
"custom_max_minutes": 120,
"preparation_seconds": 300,
"setup_and_transition_seconds_per_exercise": 60,
"estimated_seconds_per_repetition": 4,
"exercise_seconds_formula": "60 + sets * repetitions * 4 + (sets - 1) * rest_seconds",
"session_seconds_formula": "300 + sum(exercise_seconds)",
"budget_rule": "Do not exceed requested estimate, shorten rests, add sets, or duplicate patterns to fill spare time. Return a shorter session with explanation when candidates or diversity are limited.",
"precision": "planning estimate only; preparation is a time allowance, not a performed exercise or individualized warmup protocol"
},
"guidance": {
"effort": "Use a controllable load and finish with repetitions still possible; adjust downward or stop if the proposed repetitions cannot be completed with the intended technique.",
"load": "Starting suggestion only; confirm equipment and adjust after warming up. No logged value proves today's capability.",
"rest": "Rest longer if needed; actual session time may exceed the estimate.",
"recent_exposure": "Recent recorded exposure; recovery is not measured. Review how you feel; you may continue, modify, or choose another zone."
}
}