OptionalacceptOptionalaccept_OptionalblanksOptionalcard_Optionalcloze_OptionaldirectionOptionaldistractorsOptionalexamplesOptionalext_Opaque per-exercise payload for an ext: extension type. The core engine does not interpret it; the registered extension validator does. Absent on core exercises.
Optionalfrom_OptionalhintOptionalimagesOptionalmultipleOptionaloptionsOptionalpairsOptionalsentenceOptionaltilesWhich exercise renderer handles this step. A core ExerciseType value, or an ext:<vendor>-<name> extension type (ExtExerciseType) that the lesson declares in requires_extensions.
One exercise step. Type-tagged via
type.The fields are kept in a single flat shape per
typerather than per-type discriminated unions because the JSON manifests are author-edited; flat shapes are easier to read and to diff in PRs. The validator enforces type-specific requirements via model_validator instead.