Summary
Calibrations currently have no mechanism for deprecation. Score sets support deprecation by creating a new score set that supersedes the old one — setting superseded_score_set_urn on creation, which links the two via a replaces_id FK. This issue tracks adding equivalent superseding behavior to calibrations, including UI support for navigating the deprecation chain.
Problem
When a calibration needs to be updated or replaced, there is no way to mark the old calibration as deprecated or link it to its replacement. Researchers viewing a score set may encounter stale calibrations with no indication that a newer version exists. This is inconsistent with the score set lifecycle model, which explicitly supports superseding. Additionally, there is no way for a user to discover the history of a calibration — whether it was replaced, or what it replaced.
Proposed Behavior
A calibration may be superseded by another calibration belonging to the same score set. When a new calibration is created, an optional supersededCalibrationUrn field in the request body links it to the calibration it replaces. Once the superseding calibration is published:
- The superseded calibration is hidden from the default calibration list returned on the score set.
- The superseded calibration remains accessible directly by URN.
- Both
supersededCalibration and supersedingCalibration are included in the full calibration response so consumers can follow the deprecation chain.
- The UI surfaces the deprecation chain, allowing users to navigate from a superseded calibration to its replacement and vice versa.
If the superseding calibration has not yet been published, both calibrations remain visible — matching the existing behavior for score sets.
Acceptance Criteria
Implementation Notes
- The deprecation model for score sets lives on
ScoreSet as superseded_score_set_id (replaces_id in the DB) with ORM relationships superseded_score_set and supersigning_score_set. Mirror this pattern on ScoreCalibration.
- Superseding validation for score sets is done in the
ScoreSetCreate view model via a @field_validator on superseded_score_set_urn. Apply the same approach in the calibration input view model.
- Score set superseding validation enforces that the target must be a published URN (not a
tmp: URN). Apply the same rule: only a published calibration URN may be superseded.
- The visibility filter for score sets uses an
or_ on supersigning_score_set.id.is_(None) / supersigning_score_set.published_date.is_(None). Apply equivalent join-and-filter logic when building calibration queries.
- Calibrations do not have their own router today — they are managed through the score sets router. The superseding logic should be wired in at the point where calibrations are created or updated within that router.
- A calibration URN regex (
MAVEDB_CALIBRATION_URN_RE) may need to be added to src/mavedb/lib/validation/urn_re.py if it does not already exist.
- The
ShorterScoreCalibration response type (analogous to ShorterScoreSet) needs to be defined if it does not exist, containing at minimum the URN and title, so the UI can render links without fetching full calibration objects.
- The UI deprecation chain navigation should match how score set superseding is rendered — coordinate with the frontend on the expected shape of
supersededCalibration and supersedingCalibration in the API response.
Summary
Calibrations currently have no mechanism for deprecation. Score sets support deprecation by creating a new score set that supersedes the old one — setting
superseded_score_set_urnon creation, which links the two via areplaces_idFK. This issue tracks adding equivalent superseding behavior to calibrations, including UI support for navigating the deprecation chain.Problem
When a calibration needs to be updated or replaced, there is no way to mark the old calibration as deprecated or link it to its replacement. Researchers viewing a score set may encounter stale calibrations with no indication that a newer version exists. This is inconsistent with the score set lifecycle model, which explicitly supports superseding. Additionally, there is no way for a user to discover the history of a calibration — whether it was replaced, or what it replaced.
Proposed Behavior
A calibration may be superseded by another calibration belonging to the same score set. When a new calibration is created, an optional
supersededCalibrationUrnfield in the request body links it to the calibration it replaces. Once the superseding calibration is published:supersededCalibrationandsupersedingCalibrationare included in the full calibration response so consumers can follow the deprecation chain.If the superseding calibration has not yet been published, both calibrations remain visible — matching the existing behavior for score sets.
Acceptance Criteria
ScoreCalibrationmodel has a nullablesuperseded_calibration_idFK column (replaces_id) pointing to anotherScoreCalibration, with a correspondingsuperseded_calibrationrelationship andsuperseding_calibrationback-reference.replaces_idcolumn to the calibrations table.ScoreCalibrationCreate(or equivalent input view model) accepts an optionalsuperseded_calibration_urnstring field, validated againstMAVEDB_CALIBRATION_URN_RE.READpermission on the superseded calibration to reference it.SavedScoreCalibration(or equivalent response view model) includessuperseded_calibration: Optional[ShorterScoreCalibration]andsuperseding_calibration: Optional[ShorterScoreCalibration].READpermission on the superseding calibration,superseding_calibrationis masked toNonein the response.Implementation Notes
ScoreSetassuperseded_score_set_id(replaces_idin the DB) with ORM relationshipssuperseded_score_setandsupersigning_score_set. Mirror this pattern onScoreCalibration.ScoreSetCreateview model via a@field_validatoronsuperseded_score_set_urn. Apply the same approach in the calibration input view model.tmp:URN). Apply the same rule: only a published calibration URN may be superseded.or_onsupersigning_score_set.id.is_(None)/supersigning_score_set.published_date.is_(None). Apply equivalent join-and-filter logic when building calibration queries.MAVEDB_CALIBRATION_URN_RE) may need to be added tosrc/mavedb/lib/validation/urn_re.pyif it does not already exist.ShorterScoreCalibrationresponse type (analogous toShorterScoreSet) needs to be defined if it does not exist, containing at minimum the URN and title, so the UI can render links without fetching full calibration objects.supersededCalibrationandsupersedingCalibrationin the API response.