Skip to main content
Glama

update_plan_workout

Destructive

Edit ONE scheduled workout in place (keeps its identity on the calendar, and its day unless moveTo moves it): replace its interval blocks (bike/run) or strength items (gym), and/or title and/or note, and/or the session's carbohydrate (fuelG). Use for structural coaching edits — a better warm-up, changed rep count, adjusted intensities — instead of remove+re-add. Read it first with get_plan_workout. blocks/strength fully REPLACE the old content (same format as plan_workouts custom workouts; validated server-side).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
iidYes
keyNomark/unmark as the week's KEY session (see plan_workouts). You may set a limited number per week yourself; past that the rest of the edit still lands, without the star, and the result says so — a call that ONLY sets the star is refused and you ask the athlete instead. The cap is on you, not on them. Clearing one is never refused.
whyNoONE line, in the athlete's language: WHY this change — the reason from the conversation ("travel Thu-Fri, long ride moved to Sat", "deload after 3 build weeks"). The athlete's other assistant surface reads it later; without it, it sees only that the plan changed. No health details beyond what the plan needs.
dateYes
goalNothe QUALITY this session trains — why it is in the plan — a short phrase leading with the quality (as in plan_workouts); empty string hands it back to the catalog workout's own line (or none)
noteNoshort note; empty string clears it
timeNoHH:MM start of day; empty string clears
fuelGNocarbohydrate in GRAMS for the WHOLE session, overruling the app's own number for this one entry — a race rehearsal, a gut being trained up, an athlete who knows what they tolerate. The athlete sees one total, never a rate, so state it as a total. At most 120 g per hour of the session; 0 = water only; null hands it back to the formula. Leave it alone unless you have a reason the formula cannot see.
sportNofix a bike↔run mix-up on an entry that is already on the calendar, keeping its position, blocks and note. Only these two: their blocks are the same numbers read against a different threshold, while every other sport keeps a different payload entirely. Passing the entry's own sport changes nothing; any other pair is refused.
titleNo
blocksNobike/run/swim: full replacement interval structure (a swim in metres, as in plan_workouts)
moveToNoanother day to move it to, everything on it kept — a move is this one call, never copy + remove
targetNoride power|hr|rpe, run pace|hr|rpe
contextNofull-array replacement of this entry's context tags (the tag list and what each one means are in tag_activity's description — one glossary, not a second copy); empty array clears
sessionNosport 'other' only: full replacement duration + intended effort
strengthNostrength only: full replacement exercises/supersets

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / moveTo
      Added value: +{
      +  "description": "another day to move it to, everything on it kept — a move is this one call, never copy + remove",
      +  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +  "type": "string"
      +}
  2. Changed1 schema field changed
    • changedInput schema / properties / blocks / items / anyOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "children": {
      -        "items": {
      -          "properties": {
      -            "cad": {
      -              "description": "target cadence rpm",
      -              "maximum": 9007199254740991,
      -              "minimum": -9007199254740991,
      -              "type": "integer"
      -            },
      -            "dist": {
      -              "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      -              "maximum": 50000,
      -              "minimum": 25,
      -              "type": "integer"
      -            },
      -            "dur": {
      -              "description": "seconds (omit when using dist)",
      -              "exclusiveMinimum": 0,
      -              "maximum": 9007199254740991,
      -              "type": "integer"
      -            },
      -            "gear": {
      -              "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      -              "items": {
      -                "enum": [
      -                  "paddles",
      -                  "buoy",
      -                  "fins",
      -                  "board",
      -                  "snorkel"
      -                ],
      -                "type": "string"
      -              },
      -              "maxItems": 3,
      -              "type": "array"
      -            },
      -            "label": {
      -              "maxLength": 80,
      -              "type": "string"
      -            },
      -            "maxHr": {
      -              "description": "heart-rate ceiling, bpm: over it the trainer autopilot takes watts off",
      -              "maximum": 220,
      -              "minimum": 80,
      -              "type": "integer"
      -            },
      -            "maxRpe": {
      -              "description": "RPE ceiling (1-10): a rating over it, asked or tapped mid-step, takes watts off this step",
      -              "maximum": 10,
      -              "minimum": 1,
      -              "type": "integer"
      -            },
      -            "maxW": {
      -              "description": "CYCLING: the most watts ERG may hold on this step (a ceiling, e.g. 190 on an easy ride). Put limits HERE, not in the label or note — the trainer autopilot reads this field",
      -              "maximum": 2000,
      -              "minimum": 50,
      -              "type": "integer"
      -            },
      -            "mode": {
      -              "description": "SWIMMING: swim (default) | kick | pull | drill",
      -              "enum": [
      -                "swim",
      -                "kick",
      -                "pull",
      -                "drill"
      -              ],
      -              "type": "string"
      -            },
      -            "open": {
      -              "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      -              "type": "boolean"
      -            },
      -            "power": {
      -              "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      -              "maximum": 200,
      -              "minimum": 30,
      -              "type": "number"
      -            },
      -            "sft": {
      -              "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      -              "type": "boolean"
      -            },
      -            "stroke": {
      -              "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      -              "enum": [
      -                "free",
      -                "back",
      -                "breast",
      -                "fly",
      -                "im",
      -                "choice"
      -              ],
      -              "type": "string"
      -            },
      -            "target": {
      -              "description": "this step's own device target, over the session's",
      -              "enum": [
      -                "power",
      -                "pace",
      -                "hr",
      -                "rpe"
      -              ],
      -              "type": "string"
      -            },
      -            "untilLap": {
      -              "description": "the step ends when the athlete presses Lap",
      -              "type": "boolean"
      -            },
      -            "zone": {
      -              "enum": [
      -                "recovery",
      -                "endurance",
      -                "tempo",
      -                "threshold",
      -                "vo2",
      -                "sprint"
      -              ],
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "zone",
      -            "power"
      -          ],
      -          "type": "object"
      -        },
      -        "minItems": 1,
      -        "type": "array"
      -      },
      -      "reps": {
      -        "maximum": 30,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "sendoff": {
      -        "description": "SWIMMING: the send-off in seconds — the whole cycle, swim PLUS rest (\"10×100 on 1:40\" = 100). Rest is what is left of it. Use this OR a rest step inside the set, never both: they are two different sessions, and on a send-off swimming faster buys rest instead of ending the interval sooner.",
      -        "maximum": 1800,
      -        "minimum": 10,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "repeat",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "reps",
      -      "children"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "cad": {
      -        "description": "target cadence rpm",
      -        "maximum": 9007199254740991,
      -        "minimum": -9007199254740991,
      -        "type": "integer"
      -      },
      -      "dist": {
      -        "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      -        "maximum": 50000,
      -        "minimum": 25,
      -        "type": "integer"
      -      },
      -      "dur": {
      -        "description": "seconds (omit when using dist)",
      -        "exclusiveMinimum": 0,
      -        "maximum": 9007199254740991,
      -        "type": "integer"
      -      },
      -      "gear": {
      -        "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      -        "items": {
      -          "enum": [
      -            "paddles",
      -            "buoy",
      -            "fins",
      -            "board",
      -            "snorkel"
      -          ],
      -          "type": "string"
      -        },
      -        "maxItems": 3,
      -        "type": "array"
      -      },
      -      "label": {
      -        "maxLength": 80,
      -        "type": "string"
      -      },
      -      "maxHr": {
      -        "description": "heart-rate ceiling, bpm: over it the trainer autopilot takes watts off",
      -        "maximum": 220,
      -        "minimum": 80,
      -        "type": "integer"
      -      },
      -      "maxRpe": {
      -        "description": "RPE ceiling (1-10): a rating over it, asked or tapped mid-step, takes watts off this step",
      -        "maximum": 10,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "maxW": {
      -        "description": "CYCLING: the most watts ERG may hold on this step (a ceiling, e.g. 190 on an easy ride). Put limits HERE, not in the label or note — the trainer autopilot reads this field",
      -        "maximum": 2000,
      -        "minimum": 50,
      -        "type": "integer"
      -      },
      -      "mode": {
      -        "description": "SWIMMING: swim (default) | kick | pull | drill",
      -        "enum": [
      -          "swim",
      -          "kick",
      -          "pull",
      -          "drill"
      -        ],
      -        "type": "string"
      -      },
      -      "open": {
      -        "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      -        "type": "boolean"
      -      },
      -      "power": {
      -        "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      -        "maximum": 200,
      -        "minimum": 30,
      -        "type": "number"
      -      },
      -      "sft": {
      -        "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      -        "type": "boolean"
      -      },
      -      "stroke": {
      -        "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      -        "enum": [
      -          "free",
      -          "back",
      -          "breast",
      -          "fly",
      -          "im",
      -          "choice"
      -        ],
      -        "type": "string"
      -      },
      -      "target": {
      -        "description": "this step's own device target, over the session's",
      -        "enum": [
      -          "power",
      -          "pace",
      -          "hr",
      -          "rpe"
      -        ],
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "steady",
      -        "type": "string"
      -      },
      -      "untilLap": {
      -        "description": "the step ends when the athlete presses Lap",
      -        "type": "boolean"
      -      },
      -      "zone": {
      -        "enum": [
      -          "recovery",
      -          "endurance",
      -          "tempo",
      -          "threshold",
      -          "vo2",
      -          "sprint"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "zone",
      -      "power"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "children": {
      +        "items": {
      +          "properties": {
      +            "cad": {
      +              "description": "target cadence rpm",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            },
      +            "dist": {
      +              "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      +              "maximum": 50000,
      +              "minimum": 25,
      +              "type": "integer"
      +            },
      +            "dur": {
      +              "description": "seconds (omit when using dist)",
      +              "exclusiveMinimum": 0,
      +              "maximum": 9007199254740991,
      +              "type": "integer"
      +            },
      +            "gear": {
      +              "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      +              "items": {
      +                "enum": [
      +                  "paddles",
      +                  "buoy",
      +                  "fins",
      +                  "board",
      +                  "snorkel"
      +                ],
      +                "type": "string"
      +              },
      +              "maxItems": 3,
      +              "type": "array"
      +            },
      +            "hr": {
      +              "description": "the athlete's own HR corridor for this step, bpm (\"135-145\") — over the zone's band on the card, the watch and the autopilot; only when they named one",
      +              "properties": {
      +                "hi": {
      +                  "maximum": 220,
      +                  "minimum": 61,
      +                  "type": "integer"
      +                },
      +                "lo": {
      +                  "maximum": 219,
      +                  "minimum": 60,
      +                  "type": "integer"
      +                }
      +              },
      +              "required": [
      +                "lo",
      +                "hi"
      +              ],
      +              "type": "object"
      +            },
      +            "label": {
      +              "maxLength": 80,
      +              "type": "string"
      +            },
      +            "maxHr": {
      +              "description": "heart-rate ceiling, bpm: over it the trainer autopilot takes watts off",
      +              "maximum": 220,
      +              "minimum": 80,
      +              "type": "integer"
      +            },
      +            "maxRpe": {
      +              "description": "RPE ceiling (1-10): a rating over it, asked or tapped mid-step, takes watts off this step",
      +              "maximum": 10,
      +              "minimum": 1,
      +              "type": "integer"
      +            },
      +            "maxW": {
      +              "description": "CYCLING: the most watts ERG may hold on this step (a ceiling, e.g. 190 on an easy ride). Put limits HERE, not in the label or note — the trainer autopilot reads this field",
      +              "maximum": 2000,
      +              "minimum": 50,
      +              "type": "integer"
      +            },
      +            "mode": {
      +              "description": "SWIMMING: swim (default) | kick | pull | drill",
      +              "enum": [
      +                "swim",
      +                "kick",
      +                "pull",
      +                "drill"
      +              ],
      +              "type": "string"
      +            },
      +            "open": {
      +              "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      +              "type": "boolean"
      +            },
      +            "power": {
      +              "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      +              "maximum": 200,
      +              "minimum": 30,
      +              "type": "number"
      +            },
      +            "sft": {
      +              "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      +              "type": "boolean"
      +            },
      +            "stroke": {
      +              "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      +              "enum": [
      +                "free",
      +                "back",
      +                "breast",
      +                "fly",
      +                "im",
      +                "choice"
      +              ],
      +              "type": "string"
      +            },
      +            "target": {
      +              "description": "this step's own device target, over the session's",
      +              "enum": [
      +                "power",
      +                "pace",
      +                "hr",
      +                "rpe"
      +              ],
      +              "type": "string"
      +            },
      +            "untilLap": {
      +              "description": "the step ends when the athlete presses Lap",
      +              "type": "boolean"
      +            },
      +            "zone": {
      +              "enum": [
      +                "recovery",
      +                "endurance",
      +                "tempo",
      +                "threshold",
      +                "vo2",
      +                "sprint"
      +              ],
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "zone",
      +            "power"
      +          ],
      +          "type": "object"
      +        },
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "reps": {
      +        "maximum": 30,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "sendoff": {
      +        "description": "SWIMMING: the send-off in seconds — the whole cycle, swim PLUS rest (\"10×100 on 1:40\" = 100). Rest is what is left of it. Use this OR a rest step inside the set, never both: they are two different sessions, and on a send-off swimming faster buys rest instead of ending the interval sooner.",
      +        "maximum": 1800,
      +        "minimum": 10,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "repeat",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "reps",
      +      "children"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "cad": {
      +        "description": "target cadence rpm",
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "dist": {
      +        "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      +        "maximum": 50000,
      +        "minimum": 25,
      +        "type": "integer"
      +      },
      +      "dur": {
      +        "description": "seconds (omit when using dist)",
      +        "exclusiveMinimum": 0,
      +        "maximum": 9007199254740991,
      +        "type": "integer"
      +      },
      +      "gear": {
      +        "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      +        "items": {
      +          "enum": [
      +            "paddles",
      +            "buoy",
      +            "fins",
      +            "board",
      +            "snorkel"
      +          ],
      +          "type": "string"
      +        },
      +        "maxItems": 3,
      +        "type": "array"
      +      },
      +      "hr": {
      +        "description": "the athlete's own HR corridor for this step, bpm (\"135-145\") — over the zone's band on the card, the watch and the autopilot; only when they named one",
      +        "properties": {
      +          "hi": {
      +            "maximum": 220,
      +            "minimum": 61,
      +            "type": "integer"
      +          },
      +          "lo": {
      +            "maximum": 219,
      +            "minimum": 60,
      +            "type": "integer"
      +          }
      +        },
      +        "required": [
      +          "lo",
      +          "hi"
      +        ],
      +        "type": "object"
      +      },
      +      "label": {
      +        "maxLength": 80,
      +        "type": "string"
      +      },
      +      "maxHr": {
      +        "description": "heart-rate ceiling, bpm: over it the trainer autopilot takes watts off",
      +        "maximum": 220,
      +        "minimum": 80,
      +        "type": "integer"
      +      },
      +      "maxRpe": {
      +        "description": "RPE ceiling (1-10): a rating over it, asked or tapped mid-step, takes watts off this step",
      +        "maximum": 10,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "maxW": {
      +        "description": "CYCLING: the most watts ERG may hold on this step (a ceiling, e.g. 190 on an easy ride). Put limits HERE, not in the label or note — the trainer autopilot reads this field",
      +        "maximum": 2000,
      +        "minimum": 50,
      +        "type": "integer"
      +      },
      +      "mode": {
      +        "description": "SWIMMING: swim (default) | kick | pull | drill",
      +        "enum": [
      +          "swim",
      +          "kick",
      +          "pull",
      +          "drill"
      +        ],
      +        "type": "string"
      +      },
      +      "open": {
      +        "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      +        "type": "boolean"
      +      },
      +      "power": {
      +        "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      +        "maximum": 200,
      +        "minimum": 30,
      +        "type": "number"
      +      },
      +      "sft": {
      +        "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      +        "type": "boolean"
      +      },
      +      "stroke": {
      +        "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      +        "enum": [
      +          "free",
      +          "back",
      +          "breast",
      +          "fly",
      +          "im",
      +          "choice"
      +        ],
      +        "type": "string"
      +      },
      +      "target": {
      +        "description": "this step's own device target, over the session's",
      +        "enum": [
      +          "power",
      +          "pace",
      +          "hr",
      +          "rpe"
      +        ],
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "steady",
      +        "type": "string"
      +      },
      +      "untilLap": {
      +        "description": "the step ends when the athlete presses Lap",
      +        "type": "boolean"
      +      },
      +      "zone": {
      +        "enum": [
      +          "recovery",
      +          "endurance",
      +          "tempo",
      +          "threshold",
      +          "vo2",
      +          "sprint"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "zone",
      +      "power"
      +    ],
      +    "type": "object"
      +  }
      +]
  3. Changed1 schema field changed
    • changedInput schema / properties / strength / items / anyOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "mode": {
      -        "description": "kg = weight×reps, sec = timed hold/effort, m = distance-based",
      -        "enum": [
      -          "kg",
      -          "sec",
      -          "m"
      -        ],
      -        "type": "string"
      -      },
      -      "name": {
      -        "description": "exercise name, e.g. 'Back squat', 'Sled push'",
      -        "maxLength": 80,
      -        "type": "string"
      -      },
      -      "note": {
      -        "description": "optional cue: target HR, technique focus",
      -        "maxLength": 300,
      -        "type": "string"
      -      },
      -      "reps": {
      -        "description": "kg mode only",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "rpe": {
      -        "description": "target RPE 1-10 — REQUIRED on kg work, because RPE is the actual prescription and the weight is at most a starting suggestion they autoregulate from",
      -        "maximum": 10,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "sets": {
      -        "maximum": 50,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "ex",
      -        "type": "string"
      -      },
      -      "val": {
      -        "description": "kg → weight; sec → seconds; m → metres. FOR kg: 0 MEANS NO WEIGHT PRESCRIBED, and 0 is the right answer unless you actually know what they own (a fact tagged 'equipment', or they named a number in this conversation). Do not guess a round figure — an athlete with 9 kg dumbbells reads your invented 10 kg as an instruction they cannot follow. Write 0, prescribe the RPE, and say in your reply that they pick the weight.",
      -        "maximum": 100000,
      -        "minimum": 0,
      -        "type": "number"
      -      }
      -    },
      -    "required": [
      -      "name",
      -      "mode",
      -      "val",
      -      "sets"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "ex": {
      -        "items": {
      -          "properties": {
      -            "mode": {
      -              "description": "kg = weight×reps, sec = timed hold/effort, m = distance-based",
      -              "enum": [
      -                "kg",
      -                "sec",
      -                "m"
      -              ],
      -              "type": "string"
      -            },
      -            "name": {
      -              "description": "exercise name, e.g. 'Back squat', 'Sled push'",
      -              "maxLength": 80,
      -              "type": "string"
      -            },
      -            "note": {
      -              "description": "optional cue: target HR, technique focus",
      -              "maxLength": 300,
      -              "type": "string"
      -            },
      -            "reps": {
      -              "description": "kg mode only",
      -              "maximum": 1000,
      -              "minimum": 1,
      -              "type": "integer"
      -            },
      -            "rpe": {
      -              "description": "target RPE 1-10 — REQUIRED on kg work, because RPE is the actual prescription and the weight is at most a starting suggestion they autoregulate from",
      -              "maximum": 10,
      -              "minimum": 1,
      -              "type": "integer"
      -            },
      -            "val": {
      -              "description": "kg → weight; sec → seconds; m → metres. FOR kg: 0 MEANS NO WEIGHT PRESCRIBED, and 0 is the right answer unless you actually know what they own (a fact tagged 'equipment', or they named a number in this conversation). Do not guess a round figure — an athlete with 9 kg dumbbells reads your invented 10 kg as an instruction they cannot follow. Write 0, prescribe the RPE, and say in your reply that they pick the weight.",
      -              "maximum": 100000,
      -              "minimum": 0,
      -              "type": "number"
      -            }
      -          },
      -          "required": [
      -            "name",
      -            "mode",
      -            "val"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 8,
      -        "minItems": 1,
      -        "type": "array"
      -      },
      -      "sets": {
      -        "description": "shared rounds for the whole superset",
      -        "maximum": 50,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "ss",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "sets",
      -      "ex"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "mode": {
      +        "description": "kg = weight×reps, sec = timed hold/effort, m = distance-based",
      +        "enum": [
      +          "kg",
      +          "sec",
      +          "m"
      +        ],
      +        "type": "string"
      +      },
      +      "name": {
      +        "description": "exercise name, e.g. 'Back squat', 'Sled push'",
      +        "maxLength": 80,
      +        "type": "string"
      +      },
      +      "note": {
      +        "description": "optional cue: target HR, technique focus",
      +        "maxLength": 300,
      +        "type": "string"
      +      },
      +      "reps": {
      +        "description": "kg mode only",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "rpe": {
      +        "description": "target RPE 1-10 — REQUIRED on kg work, because RPE is the actual prescription and the weight is at most a starting suggestion they autoregulate from",
      +        "maximum": 10,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "sets": {
      +        "maximum": 50,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "ex",
      +        "type": "string"
      +      },
      +      "unit": {
      +        "description": "lb = this exercise's weight is in pounds (their dumbbells or a machine in lb); omit for kg. Keep the unit the athlete logs it in",
      +        "enum": [
      +          "lb"
      +        ],
      +        "type": "string"
      +      },
      +      "val": {
      +        "description": "kg → weight; sec → seconds; m → metres. FOR kg: 0 MEANS NO WEIGHT PRESCRIBED, and 0 is the right answer unless you actually know what they own (a fact tagged 'equipment', or they named a number in this conversation). Do not guess a round figure — an athlete with 9 kg dumbbells reads your invented 10 kg as an instruction they cannot follow. Write 0, prescribe the RPE, and say in your reply that they pick the weight.",
      +        "maximum": 100000,
      +        "minimum": 0,
      +        "type": "number"
      +      }
      +    },
      +    "required": [
      +      "name",
      +      "mode",
      +      "val",
      +      "sets"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "ex": {
      +        "items": {
      +          "properties": {
      +            "mode": {
      +              "description": "kg = weight×reps, sec = timed hold/effort, m = distance-based",
      +              "enum": [
      +                "kg",
      +                "sec",
      +                "m"
      +              ],
      +              "type": "string"
      +            },
      +            "name": {
      +              "description": "exercise name, e.g. 'Back squat', 'Sled push'",
      +              "maxLength": 80,
      +              "type": "string"
      +            },
      +            "note": {
      +              "description": "optional cue: target HR, technique focus",
      +              "maxLength": 300,
      +              "type": "string"
      +            },
      +            "reps": {
      +              "description": "kg mode only",
      +              "maximum": 1000,
      +              "minimum": 1,
      +              "type": "integer"
      +            },
      +            "rpe": {
      +              "description": "target RPE 1-10 — REQUIRED on kg work, because RPE is the actual prescription and the weight is at most a starting suggestion they autoregulate from",
      +              "maximum": 10,
      +              "minimum": 1,
      +              "type": "integer"
      +            },
      +            "unit": {
      +              "description": "lb = this exercise's weight is in pounds (their dumbbells or a machine in lb); omit for kg. Keep the unit the athlete logs it in",
      +              "enum": [
      +                "lb"
      +              ],
      +              "type": "string"
      +            },
      +            "val": {
      +              "description": "kg → weight; sec → seconds; m → metres. FOR kg: 0 MEANS NO WEIGHT PRESCRIBED, and 0 is the right answer unless you actually know what they own (a fact tagged 'equipment', or they named a number in this conversation). Do not guess a round figure — an athlete with 9 kg dumbbells reads your invented 10 kg as an instruction they cannot follow. Write 0, prescribe the RPE, and say in your reply that they pick the weight.",
      +              "maximum": 100000,
      +              "minimum": 0,
      +              "type": "number"
      +            }
      +          },
      +          "required": [
      +            "name",
      +            "mode",
      +            "val"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 8,
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "sets": {
      +        "description": "shared rounds for the whole superset",
      +        "maximum": 50,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "ss",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "sets",
      +      "ex"
      +    ],
      +    "type": "object"
      +  }
      +]
  4. Changed1 schema field changed
    • addedInput schema / properties / time
      Added value: +{
      +  "description": "HH:MM start of day; empty string clears",
      +  "pattern": "^(([01]\\d|2[0-3]):[0-5]\\d)?$",
      +  "type": "string"
      +}
  5. Changed1 schema field changed
    • changedInput schema / properties / note / maxLength
      Previous value: -140New value: +500
  6. Changed1 schema field changed
    • changedInput schema / properties / goal / description
      Previous value: -"WHY this session exists, one line under its name; empty string hands it back to the catalog workout's own line (or none)"New value: +"the QUALITY this session trains — why it is in the plan — a short phrase leading with the quality (as in plan_workouts); empty string hands it back to the catalog workout's own line (or none)"
  7. Changed2 schema fields changed
    • addedInput schema / properties / fuelG
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maximum": 2000,
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "carbohydrate in GRAMS for the WHOLE session, overruling the app's own number for this one entry — a race rehearsal, a gut being trained up, an athlete who knows what they tolerate. The athlete sees one total, never a rate, so state it as a total. At most 120 g per hour of the session; 0 = water only; null hands it back to the formula. Leave it alone unless you have a reason the formula cannot see."
      +}
    • addedInput schema / properties / goal
      Added value: +{
      +  "description": "WHY this session exists, one line under its name; empty string hands it back to the catalog workout's own line (or none)",
      +  "maxLength": 140,
      +  "type": "string"
      +}
  8. Changed1 schema field changed
    • changedInput schema / properties / blocks / items / anyOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "children": {
      -        "items": {
      -          "properties": {
      -            "cad": {
      -              "description": "target cadence rpm",
      -              "maximum": 9007199254740991,
      -              "minimum": -9007199254740991,
      -              "type": "integer"
      -            },
      -            "dist": {
      -              "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      -              "maximum": 50000,
      -              "minimum": 25,
      -              "type": "integer"
      -            },
      -            "dur": {
      -              "description": "seconds (omit when using dist)",
      -              "exclusiveMinimum": 0,
      -              "maximum": 9007199254740991,
      -              "type": "integer"
      -            },
      -            "gear": {
      -              "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      -              "items": {
      -                "enum": [
      -                  "paddles",
      -                  "buoy",
      -                  "fins",
      -                  "board",
      -                  "snorkel"
      -                ],
      -                "type": "string"
      -              },
      -              "maxItems": 3,
      -              "type": "array"
      -            },
      -            "label": {
      -              "maxLength": 80,
      -              "type": "string"
      -            },
      -            "maxHr": {
      -              "description": "heart-rate ceiling, bpm: over it the trainer autopilot takes watts off",
      -              "maximum": 220,
      -              "minimum": 80,
      -              "type": "integer"
      -            },
      -            "maxRpe": {
      -              "description": "RPE ceiling (1-10): a rating over it, asked or tapped mid-step, takes watts off this step",
      -              "maximum": 10,
      -              "minimum": 1,
      -              "type": "integer"
      -            },
      -            "maxW": {
      -              "description": "CYCLING: the most watts ERG may hold on this step (a ceiling, e.g. 190 on an easy ride). Put limits HERE, not in the label or note — the trainer autopilot reads this field",
      -              "maximum": 2000,
      -              "minimum": 50,
      -              "type": "integer"
      -            },
      -            "mode": {
      -              "description": "SWIMMING: swim (default) | kick | pull | drill",
      -              "enum": [
      -                "swim",
      -                "kick",
      -                "pull",
      -                "drill"
      -              ],
      -              "type": "string"
      -            },
      -            "open": {
      -              "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      -              "type": "boolean"
      -            },
      -            "power": {
      -              "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      -              "maximum": 200,
      -              "minimum": 30,
      -              "type": "number"
      -            },
      -            "sft": {
      -              "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      -              "type": "boolean"
      -            },
      -            "stroke": {
      -              "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      -              "enum": [
      -                "free",
      -                "back",
      -                "breast",
      -                "fly",
      -                "im",
      -                "choice"
      -              ],
      -              "type": "string"
      -            },
      -            "zone": {
      -              "enum": [
      -                "recovery",
      -                "endurance",
      -                "tempo",
      -                "threshold",
      -                "vo2",
      -                "sprint"
      -              ],
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "zone",
      -            "power"
      -          ],
      -          "type": "object"
      -        },
      -        "minItems": 1,
      -        "type": "array"
      -      },
      -      "reps": {
      -        "maximum": 30,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "sendoff": {
      -        "description": "SWIMMING: the send-off in seconds — the whole cycle, swim PLUS rest (\"10×100 on 1:40\" = 100). Rest is what is left of it. Use this OR a rest step inside the set, never both: they are two different sessions, and on a send-off swimming faster buys rest instead of ending the interval sooner.",
      -        "maximum": 1800,
      -        "minimum": 10,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "repeat",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "reps",
      -      "children"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "cad": {
      -        "description": "target cadence rpm",
      -        "maximum": 9007199254740991,
      -        "minimum": -9007199254740991,
      -        "type": "integer"
      -      },
      -      "dist": {
      -        "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      -        "maximum": 50000,
      -        "minimum": 25,
      -        "type": "integer"
      -      },
      -      "dur": {
      -        "description": "seconds (omit when using dist)",
      -        "exclusiveMinimum": 0,
      -        "maximum": 9007199254740991,
      -        "type": "integer"
      -      },
      -      "gear": {
      -        "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      -        "items": {
      -          "enum": [
      -            "paddles",
      -            "buoy",
      -            "fins",
      -            "board",
      -            "snorkel"
      -          ],
      -          "type": "string"
      -        },
      -        "maxItems": 3,
      -        "type": "array"
      -      },
      -      "label": {
      -        "maxLength": 80,
      -        "type": "string"
      -      },
      -      "maxHr": {
      -        "description": "heart-rate ceiling, bpm: over it the trainer autopilot takes watts off",
      -        "maximum": 220,
      -        "minimum": 80,
      -        "type": "integer"
      -      },
      -      "maxRpe": {
      -        "description": "RPE ceiling (1-10): a rating over it, asked or tapped mid-step, takes watts off this step",
      -        "maximum": 10,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "maxW": {
      -        "description": "CYCLING: the most watts ERG may hold on this step (a ceiling, e.g. 190 on an easy ride). Put limits HERE, not in the label or note — the trainer autopilot reads this field",
      -        "maximum": 2000,
      -        "minimum": 50,
      -        "type": "integer"
      -      },
      -      "mode": {
      -        "description": "SWIMMING: swim (default) | kick | pull | drill",
      -        "enum": [
      -          "swim",
      -          "kick",
      -          "pull",
      -          "drill"
      -        ],
      -        "type": "string"
      -      },
      -      "open": {
      -        "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      -        "type": "boolean"
      -      },
      -      "power": {
      -        "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      -        "maximum": 200,
      -        "minimum": 30,
      -        "type": "number"
      -      },
      -      "sft": {
      -        "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      -        "type": "boolean"
      -      },
      -      "stroke": {
      -        "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      -        "enum": [
      -          "free",
      -          "back",
      -          "breast",
      -          "fly",
      -          "im",
      -          "choice"
      -        ],
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "steady",
      -        "type": "string"
      -      },
      -      "zone": {
      -        "enum": [
      -          "recovery",
      -          "endurance",
      -          "tempo",
      -          "threshold",
      -          "vo2",
      -          "sprint"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "zone",
      -      "power"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "children": {
      +        "items": {
      +          "properties": {
      +            "cad": {
      +              "description": "target cadence rpm",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            },
      +            "dist": {
      +              "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      +              "maximum": 50000,
      +              "minimum": 25,
      +              "type": "integer"
      +            },
      +            "dur": {
      +              "description": "seconds (omit when using dist)",
      +              "exclusiveMinimum": 0,
      +              "maximum": 9007199254740991,
      +              "type": "integer"
      +            },
      +            "gear": {
      +              "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      +              "items": {
      +                "enum": [
      +                  "paddles",
      +                  "buoy",
      +                  "fins",
      +                  "board",
      +                  "snorkel"
      +                ],
      +                "type": "string"
      +              },
      +              "maxItems": 3,
      +              "type": "array"
      +            },
      +            "label": {
      +              "maxLength": 80,
      +              "type": "string"
      +            },
      +            "maxHr": {
      +              "description": "heart-rate ceiling, bpm: over it the trainer autopilot takes watts off",
      +              "maximum": 220,
      +              "minimum": 80,
      +              "type": "integer"
      +            },
      +            "maxRpe": {
      +              "description": "RPE ceiling (1-10): a rating over it, asked or tapped mid-step, takes watts off this step",
      +              "maximum": 10,
      +              "minimum": 1,
      +              "type": "integer"
      +            },
      +            "maxW": {
      +              "description": "CYCLING: the most watts ERG may hold on this step (a ceiling, e.g. 190 on an easy ride). Put limits HERE, not in the label or note — the trainer autopilot reads this field",
      +              "maximum": 2000,
      +              "minimum": 50,
      +              "type": "integer"
      +            },
      +            "mode": {
      +              "description": "SWIMMING: swim (default) | kick | pull | drill",
      +              "enum": [
      +                "swim",
      +                "kick",
      +                "pull",
      +                "drill"
      +              ],
      +              "type": "string"
      +            },
      +            "open": {
      +              "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      +              "type": "boolean"
      +            },
      +            "power": {
      +              "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      +              "maximum": 200,
      +              "minimum": 30,
      +              "type": "number"
      +            },
      +            "sft": {
      +              "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      +              "type": "boolean"
      +            },
      +            "stroke": {
      +              "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      +              "enum": [
      +                "free",
      +                "back",
      +                "breast",
      +                "fly",
      +                "im",
      +                "choice"
      +              ],
      +              "type": "string"
      +            },
      +            "target": {
      +              "description": "this step's own device target, over the session's",
      +              "enum": [
      +                "power",
      +                "pace",
      +                "hr",
      +                "rpe"
      +              ],
      +              "type": "string"
      +            },
      +            "untilLap": {
      +              "description": "the step ends when the athlete presses Lap",
      +              "type": "boolean"
      +            },
      +            "zone": {
      +              "enum": [
      +                "recovery",
      +                "endurance",
      +                "tempo",
      +                "threshold",
      +                "vo2",
      +                "sprint"
      +              ],
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "zone",
      +            "power"
      +          ],
      +          "type": "object"
      +        },
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "reps": {
      +        "maximum": 30,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "sendoff": {
      +        "description": "SWIMMING: the send-off in seconds — the whole cycle, swim PLUS rest (\"10×100 on 1:40\" = 100). Rest is what is left of it. Use this OR a rest step inside the set, never both: they are two different sessions, and on a send-off swimming faster buys rest instead of ending the interval sooner.",
      +        "maximum": 1800,
      +        "minimum": 10,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "repeat",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "reps",
      +      "children"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "cad": {
      +        "description": "target cadence rpm",
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "dist": {
      +        "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      +        "maximum": 50000,
      +        "minimum": 25,
      +        "type": "integer"
      +      },
      +      "dur": {
      +        "description": "seconds (omit when using dist)",
      +        "exclusiveMinimum": 0,
      +        "maximum": 9007199254740991,
      +        "type": "integer"
      +      },
      +      "gear": {
      +        "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      +        "items": {
      +          "enum": [
      +            "paddles",
      +            "buoy",
      +            "fins",
      +            "board",
      +            "snorkel"
      +          ],
      +          "type": "string"
      +        },
      +        "maxItems": 3,
      +        "type": "array"
      +      },
      +      "label": {
      +        "maxLength": 80,
      +        "type": "string"
      +      },
      +      "maxHr": {
      +        "description": "heart-rate ceiling, bpm: over it the trainer autopilot takes watts off",
      +        "maximum": 220,
      +        "minimum": 80,
      +        "type": "integer"
      +      },
      +      "maxRpe": {
      +        "description": "RPE ceiling (1-10): a rating over it, asked or tapped mid-step, takes watts off this step",
      +        "maximum": 10,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "maxW": {
      +        "description": "CYCLING: the most watts ERG may hold on this step (a ceiling, e.g. 190 on an easy ride). Put limits HERE, not in the label or note — the trainer autopilot reads this field",
      +        "maximum": 2000,
      +        "minimum": 50,
      +        "type": "integer"
      +      },
      +      "mode": {
      +        "description": "SWIMMING: swim (default) | kick | pull | drill",
      +        "enum": [
      +          "swim",
      +          "kick",
      +          "pull",
      +          "drill"
      +        ],
      +        "type": "string"
      +      },
      +      "open": {
      +        "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      +        "type": "boolean"
      +      },
      +      "power": {
      +        "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      +        "maximum": 200,
      +        "minimum": 30,
      +        "type": "number"
      +      },
      +      "sft": {
      +        "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      +        "type": "boolean"
      +      },
      +      "stroke": {
      +        "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      +        "enum": [
      +          "free",
      +          "back",
      +          "breast",
      +          "fly",
      +          "im",
      +          "choice"
      +        ],
      +        "type": "string"
      +      },
      +      "target": {
      +        "description": "this step's own device target, over the session's",
      +        "enum": [
      +          "power",
      +          "pace",
      +          "hr",
      +          "rpe"
      +        ],
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "steady",
      +        "type": "string"
      +      },
      +      "untilLap": {
      +        "description": "the step ends when the athlete presses Lap",
      +        "type": "boolean"
      +      },
      +      "zone": {
      +        "enum": [
      +          "recovery",
      +          "endurance",
      +          "tempo",
      +          "threshold",
      +          "vo2",
      +          "sprint"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "zone",
      +      "power"
      +    ],
      +    "type": "object"
      +  }
      +]
  9. Changed1 schema field changed
    • addedInput schema / properties / target
      Added value: +{
      +  "description": "ride power|hr|rpe, run pace|hr|rpe",
      +  "enum": [
      +    "power",
      +    "pace",
      +    "hr",
      +    "rpe"
      +  ],
      +  "type": "string"
      +}
  10. Changed3 schema fields changed
    • changedInput schema / properties / blocks / description
      Previous value: -"bike/run only: full replacement interval structure"New value: +"bike/run/swim: full replacement interval structure (a swim in metres, as in plan_workouts)"
    • changedInput schema / properties / sport / description
      Previous value: -"fix a bike↔run mix-up on an entry that is already on the calendar, keeping its position, blocks and note. Only these two: their blocks are the same numbers read against a different threshold, while every other sport keeps a different payload entirely."New value: +"fix a bike↔run mix-up on an entry that is already on the calendar, keeping its position, blocks and note. Only these two: their blocks are the same numbers read against a different threshold, while every other sport keeps a different payload entirely. Passing the entry's own sport changes nothing; any other pair is refused."
    • changedInput schema / properties / sport / enum
      Previous value: -[
      -  "cycling",
      -  "running"
      -]New value: +[
      +  "cycling",
      +  "running",
      +  "swim",
      +  "strength",
      +  "other"
      +]
  11. Changed1 schema field changed
    • changedInput schema / properties / blocks / items / anyOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "children": {
      -        "items": {
      -          "properties": {
      -            "cad": {
      -              "description": "target cadence rpm",
      -              "maximum": 9007199254740991,
      -              "minimum": -9007199254740991,
      -              "type": "integer"
      -            },
      -            "dist": {
      -              "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      -              "maximum": 50000,
      -              "minimum": 25,
      -              "type": "integer"
      -            },
      -            "dur": {
      -              "description": "seconds (omit when using dist)",
      -              "exclusiveMinimum": 0,
      -              "maximum": 9007199254740991,
      -              "type": "integer"
      -            },
      -            "gear": {
      -              "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      -              "items": {
      -                "enum": [
      -                  "paddles",
      -                  "buoy",
      -                  "fins",
      -                  "board",
      -                  "snorkel"
      -                ],
      -                "type": "string"
      -              },
      -              "maxItems": 3,
      -              "type": "array"
      -            },
      -            "label": {
      -              "maxLength": 80,
      -              "type": "string"
      -            },
      -            "mode": {
      -              "description": "SWIMMING: swim (default) | kick | pull | drill",
      -              "enum": [
      -                "swim",
      -                "kick",
      -                "pull",
      -                "drill"
      -              ],
      -              "type": "string"
      -            },
      -            "open": {
      -              "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      -              "type": "boolean"
      -            },
      -            "power": {
      -              "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      -              "maximum": 200,
      -              "minimum": 30,
      -              "type": "number"
      -            },
      -            "sft": {
      -              "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      -              "type": "boolean"
      -            },
      -            "stroke": {
      -              "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      -              "enum": [
      -                "free",
      -                "back",
      -                "breast",
      -                "fly",
      -                "im",
      -                "choice"
      -              ],
      -              "type": "string"
      -            },
      -            "zone": {
      -              "enum": [
      -                "recovery",
      -                "endurance",
      -                "tempo",
      -                "threshold",
      -                "vo2",
      -                "sprint"
      -              ],
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "zone",
      -            "power"
      -          ],
      -          "type": "object"
      -        },
      -        "minItems": 1,
      -        "type": "array"
      -      },
      -      "reps": {
      -        "maximum": 30,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "sendoff": {
      -        "description": "SWIMMING: the send-off in seconds — the whole cycle, swim PLUS rest (\"10×100 on 1:40\" = 100). Rest is what is left of it. Use this OR a rest step inside the set, never both: they are two different sessions, and on a send-off swimming faster buys rest instead of ending the interval sooner.",
      -        "maximum": 1800,
      -        "minimum": 10,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "repeat",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "reps",
      -      "children"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "cad": {
      -        "description": "target cadence rpm",
      -        "maximum": 9007199254740991,
      -        "minimum": -9007199254740991,
      -        "type": "integer"
      -      },
      -      "dist": {
      -        "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      -        "maximum": 50000,
      -        "minimum": 25,
      -        "type": "integer"
      -      },
      -      "dur": {
      -        "description": "seconds (omit when using dist)",
      -        "exclusiveMinimum": 0,
      -        "maximum": 9007199254740991,
      -        "type": "integer"
      -      },
      -      "gear": {
      -        "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      -        "items": {
      -          "enum": [
      -            "paddles",
      -            "buoy",
      -            "fins",
      -            "board",
      -            "snorkel"
      -          ],
      -          "type": "string"
      -        },
      -        "maxItems": 3,
      -        "type": "array"
      -      },
      -      "label": {
      -        "maxLength": 80,
      -        "type": "string"
      -      },
      -      "mode": {
      -        "description": "SWIMMING: swim (default) | kick | pull | drill",
      -        "enum": [
      -          "swim",
      -          "kick",
      -          "pull",
      -          "drill"
      -        ],
      -        "type": "string"
      -      },
      -      "open": {
      -        "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      -        "type": "boolean"
      -      },
      -      "power": {
      -        "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      -        "maximum": 200,
      -        "minimum": 30,
      -        "type": "number"
      -      },
      -      "sft": {
      -        "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      -        "type": "boolean"
      -      },
      -      "stroke": {
      -        "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      -        "enum": [
      -          "free",
      -          "back",
      -          "breast",
      -          "fly",
      -          "im",
      -          "choice"
      -        ],
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "steady",
      -        "type": "string"
      -      },
      -      "zone": {
      -        "enum": [
      -          "recovery",
      -          "endurance",
      -          "tempo",
      -          "threshold",
      -          "vo2",
      -          "sprint"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "zone",
      -      "power"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "children": {
      +        "items": {
      +          "properties": {
      +            "cad": {
      +              "description": "target cadence rpm",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            },
      +            "dist": {
      +              "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      +              "maximum": 50000,
      +              "minimum": 25,
      +              "type": "integer"
      +            },
      +            "dur": {
      +              "description": "seconds (omit when using dist)",
      +              "exclusiveMinimum": 0,
      +              "maximum": 9007199254740991,
      +              "type": "integer"
      +            },
      +            "gear": {
      +              "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      +              "items": {
      +                "enum": [
      +                  "paddles",
      +                  "buoy",
      +                  "fins",
      +                  "board",
      +                  "snorkel"
      +                ],
      +                "type": "string"
      +              },
      +              "maxItems": 3,
      +              "type": "array"
      +            },
      +            "label": {
      +              "maxLength": 80,
      +              "type": "string"
      +            },
      +            "maxHr": {
      +              "description": "heart-rate ceiling, bpm: over it the trainer autopilot takes watts off",
      +              "maximum": 220,
      +              "minimum": 80,
      +              "type": "integer"
      +            },
      +            "maxRpe": {
      +              "description": "RPE ceiling (1-10): a rating over it, asked or tapped mid-step, takes watts off this step",
      +              "maximum": 10,
      +              "minimum": 1,
      +              "type": "integer"
      +            },
      +            "maxW": {
      +              "description": "CYCLING: the most watts ERG may hold on this step (a ceiling, e.g. 190 on an easy ride). Put limits HERE, not in the label or note — the trainer autopilot reads this field",
      +              "maximum": 2000,
      +              "minimum": 50,
      +              "type": "integer"
      +            },
      +            "mode": {
      +              "description": "SWIMMING: swim (default) | kick | pull | drill",
      +              "enum": [
      +                "swim",
      +                "kick",
      +                "pull",
      +                "drill"
      +              ],
      +              "type": "string"
      +            },
      +            "open": {
      +              "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      +              "type": "boolean"
      +            },
      +            "power": {
      +              "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      +              "maximum": 200,
      +              "minimum": 30,
      +              "type": "number"
      +            },
      +            "sft": {
      +              "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      +              "type": "boolean"
      +            },
      +            "stroke": {
      +              "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      +              "enum": [
      +                "free",
      +                "back",
      +                "breast",
      +                "fly",
      +                "im",
      +                "choice"
      +              ],
      +              "type": "string"
      +            },
      +            "zone": {
      +              "enum": [
      +                "recovery",
      +                "endurance",
      +                "tempo",
      +                "threshold",
      +                "vo2",
      +                "sprint"
      +              ],
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "zone",
      +            "power"
      +          ],
      +          "type": "object"
      +        },
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "reps": {
      +        "maximum": 30,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "sendoff": {
      +        "description": "SWIMMING: the send-off in seconds — the whole cycle, swim PLUS rest (\"10×100 on 1:40\" = 100). Rest is what is left of it. Use this OR a rest step inside the set, never both: they are two different sessions, and on a send-off swimming faster buys rest instead of ending the interval sooner.",
      +        "maximum": 1800,
      +        "minimum": 10,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "repeat",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "reps",
      +      "children"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "cad": {
      +        "description": "target cadence rpm",
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "dist": {
      +        "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      +        "maximum": 50000,
      +        "minimum": 25,
      +        "type": "integer"
      +      },
      +      "dur": {
      +        "description": "seconds (omit when using dist)",
      +        "exclusiveMinimum": 0,
      +        "maximum": 9007199254740991,
      +        "type": "integer"
      +      },
      +      "gear": {
      +        "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      +        "items": {
      +          "enum": [
      +            "paddles",
      +            "buoy",
      +            "fins",
      +            "board",
      +            "snorkel"
      +          ],
      +          "type": "string"
      +        },
      +        "maxItems": 3,
      +        "type": "array"
      +      },
      +      "label": {
      +        "maxLength": 80,
      +        "type": "string"
      +      },
      +      "maxHr": {
      +        "description": "heart-rate ceiling, bpm: over it the trainer autopilot takes watts off",
      +        "maximum": 220,
      +        "minimum": 80,
      +        "type": "integer"
      +      },
      +      "maxRpe": {
      +        "description": "RPE ceiling (1-10): a rating over it, asked or tapped mid-step, takes watts off this step",
      +        "maximum": 10,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "maxW": {
      +        "description": "CYCLING: the most watts ERG may hold on this step (a ceiling, e.g. 190 on an easy ride). Put limits HERE, not in the label or note — the trainer autopilot reads this field",
      +        "maximum": 2000,
      +        "minimum": 50,
      +        "type": "integer"
      +      },
      +      "mode": {
      +        "description": "SWIMMING: swim (default) | kick | pull | drill",
      +        "enum": [
      +          "swim",
      +          "kick",
      +          "pull",
      +          "drill"
      +        ],
      +        "type": "string"
      +      },
      +      "open": {
      +        "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      +        "type": "boolean"
      +      },
      +      "power": {
      +        "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      +        "maximum": 200,
      +        "minimum": 30,
      +        "type": "number"
      +      },
      +      "sft": {
      +        "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      +        "type": "boolean"
      +      },
      +      "stroke": {
      +        "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      +        "enum": [
      +          "free",
      +          "back",
      +          "breast",
      +          "fly",
      +          "im",
      +          "choice"
      +        ],
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "steady",
      +        "type": "string"
      +      },
      +      "zone": {
      +        "enum": [
      +          "recovery",
      +          "endurance",
      +          "tempo",
      +          "threshold",
      +          "vo2",
      +          "sprint"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "zone",
      +      "power"
      +    ],
      +    "type": "object"
      +  }
      +]
  12. Changed1 schema field changed
    • addedInput schema / properties / why
      Added value: +{
      +  "description": "ONE line, in the athlete's language: WHY this change — the reason from the conversation (\"travel Thu-Fri, long ride moved to Sat\", \"deload after 3 build weeks\"). The athlete's other assistant surface reads it later; without it, it sees only that the plan changed. No health details beyond what the plan needs.",
      +  "maxLength": 200,
      +  "type": "string"
      +}
  13. Changed1 schema field changed
    • changedInput schema / properties / blocks / items / anyOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "children": {
      -        "items": {
      -          "properties": {
      -            "cad": {
      -              "description": "target cadence rpm",
      -              "maximum": 9007199254740991,
      -              "minimum": -9007199254740991,
      -              "type": "integer"
      -            },
      -            "dist": {
      -              "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      -              "maximum": 50000,
      -              "minimum": 25,
      -              "type": "integer"
      -            },
      -            "dur": {
      -              "description": "seconds (omit when using dist)",
      -              "exclusiveMinimum": 0,
      -              "maximum": 9007199254740991,
      -              "type": "integer"
      -            },
      -            "gear": {
      -              "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      -              "items": {
      -                "enum": [
      -                  "paddles",
      -                  "buoy",
      -                  "fins",
      -                  "board",
      -                  "snorkel"
      -                ],
      -                "type": "string"
      -              },
      -              "maxItems": 3,
      -              "type": "array"
      -            },
      -            "label": {
      -              "maxLength": 80,
      -              "type": "string"
      -            },
      -            "mode": {
      -              "description": "SWIMMING: swim (default) | kick | pull | drill",
      -              "enum": [
      -                "swim",
      -                "kick",
      -                "pull",
      -                "drill"
      -              ],
      -              "type": "string"
      -            },
      -            "open": {
      -              "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      -              "type": "boolean"
      -            },
      -            "power": {
      -              "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      -              "maximum": 200,
      -              "minimum": 30,
      -              "type": "number"
      -            },
      -            "stroke": {
      -              "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      -              "enum": [
      -                "free",
      -                "back",
      -                "breast",
      -                "fly",
      -                "im",
      -                "choice"
      -              ],
      -              "type": "string"
      -            },
      -            "zone": {
      -              "enum": [
      -                "recovery",
      -                "endurance",
      -                "tempo",
      -                "threshold",
      -                "vo2",
      -                "sprint"
      -              ],
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "zone",
      -            "power"
      -          ],
      -          "type": "object"
      -        },
      -        "minItems": 1,
      -        "type": "array"
      -      },
      -      "reps": {
      -        "maximum": 30,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "sendoff": {
      -        "description": "SWIMMING: the send-off in seconds — the whole cycle, swim PLUS rest (\"10×100 on 1:40\" = 100). Rest is what is left of it. Use this OR a rest step inside the set, never both: they are two different sessions, and on a send-off swimming faster buys rest instead of ending the interval sooner.",
      -        "maximum": 1800,
      -        "minimum": 10,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "repeat",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "reps",
      -      "children"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "cad": {
      -        "description": "target cadence rpm",
      -        "maximum": 9007199254740991,
      -        "minimum": -9007199254740991,
      -        "type": "integer"
      -      },
      -      "dist": {
      -        "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      -        "maximum": 50000,
      -        "minimum": 25,
      -        "type": "integer"
      -      },
      -      "dur": {
      -        "description": "seconds (omit when using dist)",
      -        "exclusiveMinimum": 0,
      -        "maximum": 9007199254740991,
      -        "type": "integer"
      -      },
      -      "gear": {
      -        "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      -        "items": {
      -          "enum": [
      -            "paddles",
      -            "buoy",
      -            "fins",
      -            "board",
      -            "snorkel"
      -          ],
      -          "type": "string"
      -        },
      -        "maxItems": 3,
      -        "type": "array"
      -      },
      -      "label": {
      -        "maxLength": 80,
      -        "type": "string"
      -      },
      -      "mode": {
      -        "description": "SWIMMING: swim (default) | kick | pull | drill",
      -        "enum": [
      -          "swim",
      -          "kick",
      -          "pull",
      -          "drill"
      -        ],
      -        "type": "string"
      -      },
      -      "open": {
      -        "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      -        "type": "boolean"
      -      },
      -      "power": {
      -        "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      -        "maximum": 200,
      -        "minimum": 30,
      -        "type": "number"
      -      },
      -      "stroke": {
      -        "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      -        "enum": [
      -          "free",
      -          "back",
      -          "breast",
      -          "fly",
      -          "im",
      -          "choice"
      -        ],
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "steady",
      -        "type": "string"
      -      },
      -      "zone": {
      -        "enum": [
      -          "recovery",
      -          "endurance",
      -          "tempo",
      -          "threshold",
      -          "vo2",
      -          "sprint"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "zone",
      -      "power"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "children": {
      +        "items": {
      +          "properties": {
      +            "cad": {
      +              "description": "target cadence rpm",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            },
      +            "dist": {
      +              "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      +              "maximum": 50000,
      +              "minimum": 25,
      +              "type": "integer"
      +            },
      +            "dur": {
      +              "description": "seconds (omit when using dist)",
      +              "exclusiveMinimum": 0,
      +              "maximum": 9007199254740991,
      +              "type": "integer"
      +            },
      +            "gear": {
      +              "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      +              "items": {
      +                "enum": [
      +                  "paddles",
      +                  "buoy",
      +                  "fins",
      +                  "board",
      +                  "snorkel"
      +                ],
      +                "type": "string"
      +              },
      +              "maxItems": 3,
      +              "type": "array"
      +            },
      +            "label": {
      +              "maxLength": 80,
      +              "type": "string"
      +            },
      +            "mode": {
      +              "description": "SWIMMING: swim (default) | kick | pull | drill",
      +              "enum": [
      +                "swim",
      +                "kick",
      +                "pull",
      +                "drill"
      +              ],
      +              "type": "string"
      +            },
      +            "open": {
      +              "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      +              "type": "boolean"
      +            },
      +            "power": {
      +              "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      +              "maximum": 200,
      +              "minimum": 30,
      +              "type": "number"
      +            },
      +            "sft": {
      +              "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      +              "type": "boolean"
      +            },
      +            "stroke": {
      +              "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      +              "enum": [
      +                "free",
      +                "back",
      +                "breast",
      +                "fly",
      +                "im",
      +                "choice"
      +              ],
      +              "type": "string"
      +            },
      +            "zone": {
      +              "enum": [
      +                "recovery",
      +                "endurance",
      +                "tempo",
      +                "threshold",
      +                "vo2",
      +                "sprint"
      +              ],
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "zone",
      +            "power"
      +          ],
      +          "type": "object"
      +        },
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "reps": {
      +        "maximum": 30,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "sendoff": {
      +        "description": "SWIMMING: the send-off in seconds — the whole cycle, swim PLUS rest (\"10×100 on 1:40\" = 100). Rest is what is left of it. Use this OR a rest step inside the set, never both: they are two different sessions, and on a send-off swimming faster buys rest instead of ending the interval sooner.",
      +        "maximum": 1800,
      +        "minimum": 10,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "repeat",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "reps",
      +      "children"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "cad": {
      +        "description": "target cadence rpm",
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "dist": {
      +        "description": "RUNNING and SWIMMING: measure this rep by distance in metres (2000 for 2 km on the road, 100 for a pool rep) instead of time; time is derived from the target pace. For SWIMMING this is the normal case — a set is written in metres, never in minutes. Give either dur or dist, not both.",
      +        "maximum": 50000,
      +        "minimum": 25,
      +        "type": "integer"
      +      },
      +      "dur": {
      +        "description": "seconds (omit when using dist)",
      +        "exclusiveMinimum": 0,
      +        "maximum": 9007199254740991,
      +        "type": "integer"
      +      },
      +      "gear": {
      +        "description": "SWIMMING: paddles | buoy | fins | board | snorkel",
      +        "items": {
      +          "enum": [
      +            "paddles",
      +            "buoy",
      +            "fins",
      +            "board",
      +            "snorkel"
      +          ],
      +          "type": "string"
      +        },
      +        "maxItems": 3,
      +        "type": "array"
      +      },
      +      "label": {
      +        "maxLength": 80,
      +        "type": "string"
      +      },
      +      "mode": {
      +        "description": "SWIMMING: swim (default) | kick | pull | drill",
      +        "enum": [
      +          "swim",
      +          "kick",
      +          "pull",
      +          "drill"
      +        ],
      +        "type": "string"
      +      },
      +      "open": {
      +        "description": "a maximal effort (test, all-out) — no target on the device; power stays as the expected level",
      +        "type": "boolean"
      +      },
      +      "power": {
      +        "description": "%FTP (cycling) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      +        "maximum": 200,
      +        "minimum": 30,
      +        "type": "number"
      +      },
      +      "sft": {
      +        "description": "true = the athlete's SFT: load and length come from their profile at export; follow it with 60 s easy",
      +        "type": "boolean"
      +      },
      +      "stroke": {
      +        "description": "SWIMMING: free (default) | back | breast | fly | im | choice",
      +        "enum": [
      +          "free",
      +          "back",
      +          "breast",
      +          "fly",
      +          "im",
      +          "choice"
      +        ],
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "steady",
      +        "type": "string"
      +      },
      +      "zone": {
      +        "enum": [
      +          "recovery",
      +          "endurance",
      +          "tempo",
      +          "threshold",
      +          "vo2",
      +          "sprint"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "zone",
      +      "power"
      +    ],
      +    "type": "object"
      +  }
      +]
  14. First observed

TDQS

Score is being calculated.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources