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

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
noteEditsNoYOUR OWN day notes (by:"ai") this change makes wrong, changed in the same card: replaces = the start of that note; note "" removes it, new text rewrites it, to moves it

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / context / items / enum
      Previous value: -[
      -  "workout",
      -  "heat",
      -  "altitude",
      -  "indoor",
      -  "race",
      -  "test",
      -  "group",
      -  "commute"
      -]New value: +[
      +  "workout",
      +  "heat",
      +  "altitude",
      +  "indoor",
      +  "race",
      +  "test",
      +  "group",
      +  "commute",
      +  "offroad"
      +]
  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"
      -            },
      -            "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; a sprint is 250–400) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      -              "maximum": 600,
      -              "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"
      -            },
      -            "task": {
      -              "additionalProperties": {},
      -              "description": "trainer autopilot task, cycling, only when asked: {kind:ramp,hr?,rpe?,stepPct?,everySec?} climbs until hr/rpe then ends the step; {kind:core,lo,hi} holds core °C",
      -              "properties": {
      -                "kind": {
      -                  "enum": [
      -                    "ramp",
      -                    "core"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "kind"
      -              ],
      -              "type": "object"
      -            },
      -            "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": 50,
      -        "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; a sprint is 250–400) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      -        "maximum": 600,
      -        "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"
      -      },
      -      "task": {
      -        "additionalProperties": {},
      -        "description": "trainer autopilot task, cycling, only when asked: {kind:ramp,hr?,rpe?,stepPct?,everySec?} climbs until hr/rpe then ends the step; {kind:core,lo,hi} holds core °C",
      -        "properties": {
      -          "kind": {
      -            "enum": [
      -              "ramp",
      -              "core"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "kind"
      -        ],
      -        "type": "object"
      -      },
      -      "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; a sprint is 250–400) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      +              "maximum": 600,
      +              "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"
      +            },
      +            "task": {
      +              "additionalProperties": {},
      +              "description": "autopilot task, cycling, only when asked: {kind:ramp,hr?,rpe?,stepPct?,everySec?} climbs until hr/rpe then ends the step; {kind:core,lo,hi} holds core °C, top 39.5: a guide, sensor reads low, no heat-dose proof",
      +              "properties": {
      +                "kind": {
      +                  "enum": [
      +                    "ramp",
      +                    "core"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "kind"
      +              ],
      +              "type": "object"
      +            },
      +            "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": 50,
      +        "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; a sprint is 250–400) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      +        "maximum": 600,
      +        "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"
      +      },
      +      "task": {
      +        "additionalProperties": {},
      +        "description": "autopilot task, cycling, only when asked: {kind:ramp,hr?,rpe?,stepPct?,everySec?} climbs until hr/rpe then ends the step; {kind:core,lo,hi} holds core °C, top 39.5: a guide, sensor reads low, no heat-dose proof",
      +        "properties": {
      +          "kind": {
      +            "enum": [
      +              "ramp",
      +              "core"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "kind"
      +        ],
      +        "type": "object"
      +      },
      +      "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"
      -      },
      -      "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"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "load": {
      +        "description": "sec and m modes only: the kg carried or pushed — a farmer's carry is mode m, val 50, load 32. Omit when there is none or you do not know it; not in the name",
      +        "maximum": 1000,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "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', they named a number in this conversation, or the log holds a load for this exercise: start from that). 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": {
      +            "load": {
      +              "description": "sec and m modes only: the kg carried or pushed — a farmer's carry is mode m, val 50, load 32. Omit when there is none or you do not know it; not in the name",
      +              "maximum": 1000,
      +              "minimum": 0,
      +              "type": "number"
      +            },
      +            "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', they named a number in this conversation, or the log holds a load for this exercise: start from that). 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. Changed2 schema fields 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"
      -            },
      -            "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"
      -            },
      -            "task": {
      -              "additionalProperties": {},
      -              "description": "trainer autopilot task, cycling, only when asked: {kind:ramp,hr?,rpe?,stepPct?,everySec?} climbs until hr/rpe then ends the step; {kind:core,lo,hi} holds core °C",
      -              "properties": {
      -                "kind": {
      -                  "enum": [
      -                    "ramp",
      -                    "core"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "kind"
      -              ],
      -              "type": "object"
      -            },
      -            "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": 50,
      -        "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"
      -      },
      -      "task": {
      -        "additionalProperties": {},
      -        "description": "trainer autopilot task, cycling, only when asked: {kind:ramp,hr?,rpe?,stepPct?,everySec?} climbs until hr/rpe then ends the step; {kind:core,lo,hi} holds core °C",
      -        "properties": {
      -          "kind": {
      -            "enum": [
      -              "ramp",
      -              "core"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "kind"
      -        ],
      -        "type": "object"
      -      },
      -      "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; a sprint is 250–400) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      +              "maximum": 600,
      +              "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"
      +            },
      +            "task": {
      +              "additionalProperties": {},
      +              "description": "trainer autopilot task, cycling, only when asked: {kind:ramp,hr?,rpe?,stepPct?,everySec?} climbs until hr/rpe then ends the step; {kind:core,lo,hi} holds core °C",
      +              "properties": {
      +                "kind": {
      +                  "enum": [
      +                    "ramp",
      +                    "core"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "kind"
      +              ],
      +              "type": "object"
      +            },
      +            "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": 50,
      +        "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; a sprint is 250–400) or %threshold pace (running) or %CSS (swimming — 100 = their CSS pace, below 100 = slower/easier, e.g. 92 for an aerobic set)",
      +        "maximum": 600,
      +        "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"
      +      },
      +      "task": {
      +        "additionalProperties": {},
      +        "description": "trainer autopilot task, cycling, only when asked: {kind:ramp,hr?,rpe?,stepPct?,everySec?} climbs until hr/rpe then ends the step; {kind:core,lo,hi} holds core °C",
      +        "properties": {
      +          "kind": {
      +            "enum": [
      +              "ramp",
      +              "core"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "kind"
      +        ],
      +        "type": "object"
      +      },
      +      "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"
      +  }
      +]
    • addedInput schema / properties / noteEdits
      Added value: +{
      +  "description": "YOUR OWN day notes (by:\"ai\") this change makes wrong, changed in the same card: replaces = the start of that note; note \"\" removes it, new text rewrites it, to moves it",
      +  "items": {
      +    "properties": {
      +      "date": {
      +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +        "type": "string"
      +      },
      +      "note": {
      +        "maxLength": 1000,
      +        "type": "string"
      +      },
      +      "replaces": {
      +        "maxLength": 200,
      +        "minLength": 4,
      +        "type": "string"
      +      },
      +      "to": {
      +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "date",
      +      "replaces"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 10,
      +  "type": "array"
      +}
  5. 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"
      -            },
      -            "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": 50,
      -        "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"
      -  }
      -]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"
      +            },
      +            "task": {
      +              "additionalProperties": {},
      +              "description": "trainer autopilot task, cycling, only when asked: {kind:ramp,hr?,rpe?,stepPct?,everySec?} climbs until hr/rpe then ends the step; {kind:core,lo,hi} holds core °C",
      +              "properties": {
      +                "kind": {
      +                  "enum": [
      +                    "ramp",
      +                    "core"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "kind"
      +              ],
      +              "type": "object"
      +            },
      +            "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": 50,
      +        "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"
      +      },
      +      "task": {
      +        "additionalProperties": {},
      +        "description": "trainer autopilot task, cycling, only when asked: {kind:ramp,hr?,rpe?,stepPct?,everySec?} climbs until hr/rpe then ends the step; {kind:core,lo,hi} holds core °C",
      +        "properties": {
      +          "kind": {
      +            "enum": [
      +              "ramp",
      +              "core"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "kind"
      +        ],
      +        "type": "object"
      +      },
      +      "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"
      +  }
      +]
  6. 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"
      -            },
      -            "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"
      -  }
      -]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": 50,
      +        "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"
      +  }
      +]
  7. 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"
      +}
  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"
      -            },
      -            "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"
      +  }
      +]
  9. 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"
      +  }
      +]
  10. 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"
      +}
  11. Changed1 schema field changed
    • changedInput schema / properties / note / maxLength
      Previous value: -140New value: +500
  12. 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)"
  13. 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"
      +}
  14. 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"
      +  }
      +]
  15. 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"
      +}
  16. 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"
      +]
  17. 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"
      +  }
      +]
  18. 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"
      +}
  19. 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"
      +  }
      +]
  20. First observed

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, but the description adds the crucial detail that blocks/strength fully REPLACE rather than merge with existing content and are validated server-side, which is exactly the behavioral fact an agent needs before overwriting a plan entry. It also discloses that the day is preserved unless moveTo is used. It does not mention partial-failure or refusal behavior (the key-star cap is only documented inside the parameter schema).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the core action and scope before alternatives and format notes; there is no filler. The heavy parenthetical nesting (identity, day unless moveTo, and/or chains) makes it slightly denser to parse than ideal, but every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 17-parameter nested mutation tool with no output schema, the description covers the action, its destructive replacement nature, the read-first workflow, and the format contract for blocks. Remaining gaps — response shape, validation error behavior, and the key-star cap that lives only in the schema — are mostly carried by the unusually rich schema descriptions, so this is close to complete rather than deficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 82%, so the baseline is 3, and the description earns above that by explaining replacement semantics for blocks and strength, the required payload format parity with plan_workouts custom workouts, and that moveTo relocates rather than copies. Those points add real meaning beyond the field-level descriptions, though it does not touch the many nested step fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with precise scope: edits ONE scheduled workout in place, preserving its calendar identity and day unless moveTo moves it, replacing interval blocks, strength items, title, note, or fuelG. It explicitly distinguishes itself from the remove+re-add pattern and pairs with get_plan_workout for reading first, so an agent can tell it apart from siblings like update_plan_workouts without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear when-to-use guidance — structural coaching edits such as a better warm-up, changed rep count, adjusted intensities — and explicitly names the rejected alternative (remove + re-add). It also states the prerequisite to read the workout first. It stops short of naming the plural sibling update_plan_workouts or stating when a multi-workout edit should switch tools, so it is short of a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources