Picarones / docs /explanation /versioning.md
Claude
chore(versioning): S0-bis — fix leftover dettes from S0
13ba1e5 unverified
# Politique de versionning
> Comment Picarones numérote ses versions, et pourquoi.
## Résumé
Picarones suit **Semantic Versioning 2.0.0** strict :
`MAJOR.MINOR.PATCH` avec suffixes pré-release PEP 440 (`-rc1`,
`-beta1`, `-alpha1`).
**État courant** : `0.9.0` — phase pré-1.0. Architecture stable,
surface fonctionnelle en construction.
**Cible** : `1.0.0` — release publique avec UI, rapport refondu et
parité des importeurs livrés.
---
## SemVer pré-1.0 : qu'est-ce que ça change ?
En `0.x`, SemVer autorise **les ruptures sans préavis**. Picarones
les annonce explicitement dans le `CHANGELOG.md` mais ne garantit
pas de période de dépréciation. C'est précisément l'intérêt du
pré-1.0 : pouvoir corriger l'API publique sans empêcher la
progression.
Concrètement :
- les schémas JSON (`BenchmarkResult`, `run_manifest.json`,
`pipeline_results.jsonl`, `view_results.jsonl`) **peuvent évoluer**
entre `0.9.x` et `0.10.x` ;
- les noms de paramètres CLI **peuvent changer** ;
- les endpoints HTTP **peuvent être renommés ou retirés** ;
- les contrats internes (Pydantic models de `picarones.domain`)
**peuvent être modifiés**.
Chaque rupture est documentée dans le `CHANGELOG.md` sous la section
`### BREAKING`.
À partir de `1.0.0`, la politique se durcit : période de
dépréciation minimum d'une mineure, retrait à la majeure suivante.
---
## Mapping version ↔ tag git
Le numéro de version est dérivé du **tag git** par
`setuptools_scm`. Pas de version codée en dur dans `pyproject.toml`.
| Contexte | Version produite |
|---|---|
| Tag `v0.9.0` posé sur un commit | `0.9.0` |
| 5 commits après `v0.9.0` (sans nouveau tag) | `0.9.1.dev5+g<sha>` |
| Tag `v0.10.0-rc1` | `0.10.0rc1` (PEP 440) |
| Sans aucun tag (tarball, repo neuf) | `0.9.0` (fallback) |
Le scheme `setuptools_scm` est `guess-next-dev` : les builds
intermédiaires suggèrent un patch à venir (`0.9.1.devN`). Un bump
de mineure (`0.10.0`) ou majeure (`1.0.0`) est **toujours explicite**
via un nouveau tag git.
Le `fallback_version` de `pyproject.toml` est synchronisé avec
`picarones/domain/_version_fallback.py:FALLBACK_VERSION`. Un test
d'architecture (`tests/architecture/test_single_version_source.py`)
vérifie cette cohérence.
---
## Roadmap vers 1.0.0
La sortie de `1.0.0` est conditionnée à la livraison de :
1. **Surface UI complète** — exposition de tous les champs du modèle
`BenchmarkRunRequest`, refonte du rapport HTML, parité fonctionnelle
avec la CLI (`compare`, `robustness`, `history`).
2. **Parité importeurs corpus** — IIIF, Gallica, eScriptorium accessibles
depuis l'UI web (en plus de HTR-United et HuggingFace déjà présents).
3. **Refonte rapport HTML** — passage à l'IA 4 onglets (Overview / Engines
/ Documents / Crosses) en gardant la stack Jinja2.
Les versions intermédiaires `0.10.0`, `0.11.0`, etc. peuvent être
publiées au fil du chantier ; elles sont des jalons techniques, pas
des releases publiques.
---
## Pourquoi `0.9.0` plutôt que `2.0.x` ou `3.0.0` ?
L'historique interne du projet utilisait une dénomination « v2.0 »
pour désigner l'aboutissement du rewrite architectural en 8 couches
(mai 2026). Cette dénomination reflétait un cycle de refactor
interne, pas une maturité fonctionnelle publique : à ce moment, le
projet n'avait ni interface utilisateur finalisée, ni parité
importeurs, ni rapport refondu.
Le repositionnement en `0.9.0` (mai 2026) aligne le numéro de
version sur la maturité réelle : architecture solide, surface
fonctionnelle en construction. La sortie de `1.0.0` deviendra un
événement public marquant (UI complète, rapport refondu, parité
importeurs), ce qui correspond à l'usage habituel d'un saut
`0.x → 1.0`.
Ce choix est documenté dans la note de repositionnement de
[`docs/archive/README.md`](../archive/README.md) et dans la première
entrée du [`CHANGELOG.md`](../../CHANGELOG.md) post-repositionnement.
---
## Source unique de vérité (anti-dérive)
La version courante est définie à **un seul endroit** : le tag git le
plus récent, lu par `setuptools_scm`.
Le fallback (utilisé en l'absence de tag) est défini à **un seul
endroit** : `picarones/domain/_version_fallback.py:FALLBACK_VERSION`. La
constante équivalente `fallback_version` dans `pyproject.toml` doit
rester synchronisée — un test d'architecture le vérifie.
**Règle de codage** : interdiction de coder un numéro de version en
dur ailleurs que dans ces deux fichiers. Tout consommateur doit
lire `picarones.__version__` (ou ses équivalents internes
`_resolve_picarones_version()` pour les couches qui ne peuvent pas
importer le package racine).
---
## Procédure de release
Voir [`docs/operations/release-process.md`](../operations/release-process.md)
pour la procédure complète. Le résumé :
```bash
# 1. Mettre à jour CHANGELOG.md (section ## [X.Y.Z] — YYYY-MM-DD)
git commit -am "docs(changelog): release 0.10.0"
# 2. Tag annoté
git tag -a v0.10.0 -m "Picarones 0.10.0"
git push origin main v0.10.0
# 3. Le workflow .github/workflows/release.yml déclenche
# automatiquement build + TestPyPI + PyPI + Docker + GitHub Release.
```