Introduce a first-class Algorithm Version (Major.Minor) that operator and experiment developers declare independently of the Python package version, governed by these rules (related to #936 ):
| Change type |
Action |
| Logging, refactoring, memory/performance optimisation, comments |
No version bump |
| Adding new outputs or inputs while keeping existing behaviour identical |
Minor bump (e.g. v1.0 → v1.1) |
| Any change to the mathematical definition or computation |
Major bump (e.g. v1.1 → v2.0) |
From a developer perspective:
- Every operator declares an Algorithm Version as part of its metadata, independently of its package version.
- Every experiment (including custom experiments registered via decorator) declares an Algorithm Version.
- The Algorithm Version is the developer's assertion of semantic sameness: same major version means "results computed by this algorithm are interchangeable regardless of what package version produced them."
From a user perspective:
- When a discoveryspace is created, the algorithm versions of all experiments in its measurement space are frozen at creation time. Old spaces remain valid historical artefacts even after an algorithm is upgraded.
- When an algorithm major version is bumped, new spaces created will automatically use the new version and existing memoised results from the old version are not reused — re-measurement happens automatically without any user action.
- When only a minor version bump occurs (extension), existing memoised results remain valid and are reused.
- Users do not need to specify algorithm versions in space YAML; they are resolved from the experiment catalog at space creation time.
NOTE: With the versioning scheme you can only have ONE installed version of an experiment/operator. This is already the case for operators. For experiments to maintain multiple executable versions you would need to adopt a different method
Describe alternatives you've considered.
-
Embedding the algorithm version in the experiment base name (e.g. solve_mip_v2): one of the current solutions. This makes versioning explicit in the identifier but ties the algorithm generation to the human-readable name, requiring users to change YAML when upgrading. For decorated experiments it also requires changing the function name. Rejected in favour of a separate version field that is encoded automatically into memoisation keys.
-
Supporting multiple algorithm versions coexisting in the catalog simultaneously (e.g. allowing a space YAML to explicitly request solve_mip at v1 even after v2 is deployed): this would allow controlled migration and side-by-side comparison. Deferred because it requires significant changes to catalog internals and is incompatible with the decorator-based experiment registration pattern. The "frozen space at creation time" behaviour covers the most common need without this complexity.
Additional context.
The major algorithm version is the only component that affects memoisation. The minor version is informational — it records that an experiment was extended — but does not break compatibility with existing results. Both components should be stored on created resources as a frozen-at-creation-time snapshot for reproducibility auditing.
Operators without a declared Algorithm Version should produce a deprecation warning at registration time to drive adoption.
Introduce a first-class Algorithm Version (
Major.Minor) that operator and experiment developers declare independently of the Python package version, governed by these rules (related to #936 ):v1.0 → v1.1)v1.1 → v2.0)From a developer perspective:
From a user perspective:
NOTE: With the versioning scheme you can only have ONE installed version of an experiment/operator. This is already the case for operators. For experiments to maintain multiple executable versions you would need to adopt a different method
Describe alternatives you've considered.
Embedding the algorithm version in the experiment base name (e.g.
solve_mip_v2): one of the current solutions. This makes versioning explicit in the identifier but ties the algorithm generation to the human-readable name, requiring users to change YAML when upgrading. For decorated experiments it also requires changing the function name. Rejected in favour of a separate version field that is encoded automatically into memoisation keys.Supporting multiple algorithm versions coexisting in the catalog simultaneously (e.g. allowing a space YAML to explicitly request
solve_mipatv1even afterv2is deployed): this would allow controlled migration and side-by-side comparison. Deferred because it requires significant changes to catalog internals and is incompatible with the decorator-based experiment registration pattern. The "frozen space at creation time" behaviour covers the most common need without this complexity.Additional context.
The major algorithm version is the only component that affects memoisation. The minor version is informational — it records that an experiment was extended — but does not break compatibility with existing results. Both components should be stored on created resources as a frozen-at-creation-time snapshot for reproducibility auditing.
Operators without a declared Algorithm Version should produce a deprecation warning at registration time to drive adoption.