Skip to content

Commit 9529650

Browse files
OneMuppetclaude
andcommitted
Add versioning spec for the standard
Defines the stability contract (7 levels, 8 categories, benchmark schema), semver rules with concrete OP examples, core vs extension data file separation, deprecation process, and release checklist. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0d51033 commit 9529650

1 file changed

Lines changed: 170 additions & 0 deletions

File tree

spec/versioning.md

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# OpenProgression Versioning
2+
3+
**Version:** 1.0.0
4+
5+
## Overview
6+
7+
OpenProgression is a standard, not just a codebase. Gym software, coaching platforms, and developer tools consume OP data and depend on its structure being stable. This document defines how the standard evolves without breaking existing consumers.
8+
9+
The core principle: **additive changes are free, breaking changes require a major version bump and a migration path.**
10+
11+
## Version Format
12+
13+
OP follows [Semantic Versioning](https://semver.org/) applied to a data standard:
14+
15+
```
16+
MAJOR.MINOR.PATCH
17+
```
18+
19+
- **MAJOR** -- Breaking changes to existing schemas, level definitions, or category structure
20+
- **MINOR** -- Additive extensions (new data files, new optional fields, new movements)
21+
- **PATCH** -- Corrections (benchmark value adjustments, typo fixes, source citation updates)
22+
23+
The version number applies to the standard as a whole. Individual data files carry a `"version"` field that tracks the standard version they conform to.
24+
25+
## The Stability Contract
26+
27+
These are the things consumers can depend on. Breaking any of these requires a major version bump.
28+
29+
### Core guarantees (MAJOR version)
30+
31+
| Guarantee | What it means |
32+
|-----------|---------------|
33+
| **7 levels** | The level IDs, names, numbers (1-7), and percentile ranges in `data/levels.json` do not change |
34+
| **8 categories** | The category IDs and names in `data/categories.json` do not change |
35+
| **Benchmark schema** | The shape of `data/benchmarks/*.json` does not change -- `standards`, `bwMultiplier`, `sources` fields remain stable |
36+
| **Level calculation** | The weakest-link principle and the method for determining an athlete's level do not change |
37+
| **Gender differentiation** | All benchmarks provide both `male` and `female` values |
38+
| **Source traceability** | Every benchmark value traces to a citable source in `data/sources.json` |
39+
40+
An application that reads `data/levels.json`, `data/categories.json`, and `data/benchmarks/*.json` will continue to work across all minor and patch releases without code changes.
41+
42+
### Extension guarantees (MINOR version)
43+
44+
New data files, new optional fields, and new spec documents are additive. They never modify the schema of existing files. Consumers that don't use the new data are unaffected.
45+
46+
Examples of minor changes:
47+
- Adding a new data file (e.g., `data/milestones.json`, `data/progressions.json`)
48+
- Adding a new benchmark movement to an existing category file
49+
- Adding optional fields to existing schemas (fields that weren't there before)
50+
- Adding new spec documents (e.g., `spec/progressions.md`)
51+
- Adding new source citations to `data/sources.json`
52+
53+
### Correction guarantees (PATCH version)
54+
55+
Benchmark values can be adjusted within a patch release when evidence shows a number is wrong. These are not treated as breaking changes because the standard's purpose is accuracy -- a benchmark that's provably off should be corrected.
56+
57+
Examples of patch changes:
58+
- Adjusting a benchmark value based on new research or community review
59+
- Fixing a typo in a description or citation
60+
- Correcting a source URL
61+
- Updating `notes` fields
62+
63+
## What Counts as Breaking
64+
65+
Any change that would cause an existing consumer to produce incorrect results, crash, or need code changes:
66+
67+
| Change | Why it breaks |
68+
|--------|--------------|
69+
| Removing or renaming a level | Apps display level names, store level IDs |
70+
| Changing the number of levels (adding Level 8, removing a level) | UI layouts, color mappings, percentile logic |
71+
| Removing or renaming a category | Benchmark lookups, category-based filtering |
72+
| Changing the number of categories | Radar charts, UI grids, overall level calculation |
73+
| Removing a field from the benchmark schema | Deserialization fails, null references |
74+
| Changing the `standards` key names (e.g., `beginner` to `level_1`) | Every lookup breaks |
75+
| Changing the weakest-link principle | Level calculation logic changes |
76+
| Changing units mid-category (kg to lb, seconds to minutes) | Every comparison breaks |
77+
78+
## Extensions vs. Core
79+
80+
The standard distinguishes between **core** data (the stability contract) and **extensions** (additive features).
81+
82+
### Core data files
83+
84+
These files are covered by the stability contract. Their schemas are frozen within a major version:
85+
86+
```
87+
data/levels.json
88+
data/categories.json
89+
data/benchmarks/*.json
90+
data/sources.json
91+
```
92+
93+
### Extension data files
94+
95+
These files provide additional functionality. They are additive and optional -- an implementation that ignores them is still a complete OP implementation:
96+
97+
```
98+
data/metcons.json (added in 1.0.0)
99+
data/sessions.json (added in 1.0.0)
100+
data/milestones.json (proposed in 1.1.0)
101+
data/progressions.json (proposed in 1.1.0)
102+
```
103+
104+
Extensions follow the same versioning rules once introduced. After an extension ships in a minor release, its schema is stable within that major version.
105+
106+
### How to tell if something is core or extension
107+
108+
If removing it would break the "7 levels, 8 categories" level assessment system, it's core. Everything else is an extension.
109+
110+
## Adding New Content
111+
112+
### New movements within existing categories
113+
114+
Adding a new benchmark movement (e.g., Wall Ball to Bodyweight) is a **minor** change. The category file gains a new entry, but existing entries are untouched. Consumers that iterate over all movements in a category will pick up the new one automatically. Consumers that look up specific movements by ID are unaffected.
115+
116+
### New categories
117+
118+
Adding a 9th category would be a **major** change. It changes the weakest-link calculation (overall level now depends on 9 categories instead of 8), breaks UI layouts built for 8 categories, and changes the "8 categories" part of the standard's identity.
119+
120+
If a new domain needs to be tracked, consider whether it can be added as movements within an existing category before creating a new one.
121+
122+
### New levels
123+
124+
Adding an 8th level or splitting an existing level would be a **major** change. It changes percentile boundaries, color mappings, and the "7 levels" identity.
125+
126+
Foundation Milestones (F1, F2, F3) are explicitly **not levels** -- they are an extension that provides sub-Beginner progress markers without modifying the level system. This is the correct pattern for adding granularity without breaking the core.
127+
128+
### New data files
129+
130+
Adding a new data file is always a **minor** change. The file is additive and consumers that don't read it are unaffected.
131+
132+
## Version Number Propagation
133+
134+
When a release is made, the version number updates in:
135+
136+
1. **All data file `"version"` fields** -- every JSON file with a `"version"` key gets the new standard version
137+
2. **All spec document `**Version:**` headers** -- every `.md` file in `spec/` gets the new version
138+
3. **The website footer** (`v1.0.0` badge)
139+
4. **The README** (standard version badge)
140+
141+
This keeps everything in sync and makes it easy to verify which version of the standard a file conforms to.
142+
143+
## Deprecation Process
144+
145+
If a field, movement, or data file needs to be removed in a future major version:
146+
147+
1. **Announce** -- mark it as deprecated in the current minor release (add a `"deprecated": true` field or a note in the spec)
148+
2. **Document** -- explain what replaces it and why
149+
3. **Wait** -- deprecated items remain functional for at least one minor release cycle
150+
4. **Remove** -- the next major version can remove deprecated items
151+
152+
This gives consumers time to migrate.
153+
154+
## Release Checklist
155+
156+
For any OP release:
157+
158+
- [ ] Determine version bump type (major / minor / patch)
159+
- [ ] Update version numbers in all data files and spec documents
160+
- [ ] Update the changelog (if one exists) or the GitHub release notes
161+
- [ ] Run `node scripts/validate-data.mjs` -- all checks pass
162+
- [ ] Build the website -- `cd website && npm run build` succeeds
163+
- [ ] Tag the release in git: `git tag v1.x.x`
164+
- [ ] Update the website version badge
165+
166+
## Version History
167+
168+
| Version | Date | Type | Summary |
169+
|---------|------|------|---------|
170+
| 1.0.0 | 2025-02-17 | Initial | 7 levels, 8 categories, 25 benchmark movements, scaled programming, metcon library |

0 commit comments

Comments
 (0)