Skip to content

feat(0.5.2): le socle borne le moteur, et le garde-fou nomme ce qu'il écarte - #321

Merged
stephrobert merged 1 commit into
mainfrom
feat/socle-borne-le-moteur
Oct 17, 2026
Merged

stephrobert merged 1 commit into
mainfrom
feat/socle-borne-le-moteur

Conversation

@stephrobert

Copy link
Copy Markdown
Owner

Ce que sept catalogues neufs ont révélé

Créés le 2026-10-17 par new catalog 0.5.1, ils portaient deux appels au moteur, aucun borné :

.github/workflows/ci.yml      uv tool install dsoxlab
.pre-commit-config.yaml       entry: dsoxlab validate-structure

Le second est le pire : il emploie le dsoxlab du PATH, c'est-à-dire ce qui traîne sur la machine du contributeur.

Les douze catalogues établis venaient d'être alignés sur uvx 'dsoxlab>=0.5.0' le même jour. Tout catalogue neuf naissait donc avec la dette qu'on venait de solder, et sous une forme que la correction ne couvrait pas : elle cherchait uvx dsoxlab, pas uv tool install ni entry:.

Quelle borne, et pourquoi celle-là

La version qui écrit le catalogue : la seule affirmable sans analyser son contenu. Un socle produit par la 0.5.2 suppose au moins la 0.5.2. Une valeur figée dans le gabarit se périmerait au premier contrat qui gagne un champ, ce qui est exactement le défaut corrigé.

C'est la version installée qui est lue, par importlib.metadata, et non celle du pyproject.toml. Juste après ce bump, le socle borne donc encore à 0.5.1 jusqu'à réinstallation du tool. C'est voulu : la borne doit nommer un moteur qui existe sur PyPI, pas un numéro qu'aucun uvx ne saurait satisfaire.

Les uv tool install dsoxlab des README et des CONTRIBUTING restent nus à dessein : ils s'adressent à un apprenant, qui doit prendre la dernière version. Ce sont des instructions, pas des appels.

Le garde-fou annonçait un accord en écartant un tiers du disque

scripts/gen-catalogues.py --mesurer répondait « manifeste en accord avec le disque (12 catalogues) » quand le disque en portait dix-neuf. Une seule ligne, if labs:, sautait en silence tout catalogue sans lab.

Le filtre se défend : dsoxlab catalog list n'a rien à proposer d'un catalogue vide. Le message, non. Et c'est le défaut même que ce script existait pour empêcher : la liste avait déjà été écrite une fois avec six entrées quand le disque en portait douze, et 901 messages avaient été sautés sans qu'aucun contrôle le dise. Partir du disque ne suffit pas, il faut dire ce qu'on en écarte.

Un second défaut se cachait derrière le premier : un catalogue inscrit au manifeste qui tombait à zéro lab était signalé « introuvable sur le disque : vérifie qu'il n'a pas été renommé », envoyant chercher un renommage qui n'avait pas eu lieu.

Deux cliquets, prouvés par trois mutations

tests/test_socle_du_catalogue.py refuse tout appel non borné dans ce que le socle exécute, et vérifie que la borne vaut la version du moteur et non une valeur figée. Les commentaires qui citent uvx dsoxlab pour expliquer pourquoi on ne l'emploie pas sont exemptés, sans quoi la justification serait impossible à écrire.

mutation effet
le CI revient à l'appel nu rouge
le hook revient au moteur du PATH rouge
une borne figée au gabarit rouge

Les deux premières sont les défauts exactement observés sur les sept catalogues.

Vérifié

pytest tests/                    1611 passed
tests du socle                   19 passed, dont 2 nouveaux
ruff check src/ tests/ scripts/  All checks passed
mypy src/dsoxlab/                97 fichiers, aucune erreur
complexite / code-mort / écran   les trois cliquets verts
gen-catalogues.py --mesurer      nomme les 7, compare les 12
uv lock                          0.5.1 → 0.5.2

🤖 Generated with Claude Code

… écarte

CE QUE SEPT CATALOGUES NEUFS ONT RÉVÉLÉ

Créés le 2026-10-17 par `new catalog` 0.5.1, ils portaient deux appels au
moteur, et aucun n'était borné :

    .github/workflows/ci.yml      uv tool install dsoxlab
    .pre-commit-config.yaml       entry: dsoxlab validate-structure

Le second est le pire : il emploie le `dsoxlab` du PATH, c'est-à-dire ce qui
traîne sur la machine du contributeur, quelle qu'en soit la version.

Les douze catalogues établis venaient d'être alignés sur `uvx 'dsoxlab>=0.5.0'`
le même jour. Tout catalogue neuf naissait donc avec la dette qu'on venait de
solder, et sous une forme que la correction ne couvrait même pas, puisqu'elle
cherchait `uvx dsoxlab` et non `uv tool install` ni `entry:`.

QUELLE BORNE, ET POURQUOI CELLE-LÀ

La version qui ÉCRIT le catalogue. C'est la seule affirmable sans analyser son
contenu : un socle produit par la 0.5.2 suppose au moins la 0.5.2. Une valeur
figée dans le gabarit se périmerait au premier contrat qui gagne un champ, ce
qui est exactement le défaut corrigé.

C'est la version INSTALLÉE qui est lue, par `importlib.metadata`, et non celle
du `pyproject.toml`. Juste après ce bump, le socle borne donc encore à 0.5.1
jusqu'à réinstallation du tool. C'est voulu : la borne doit nommer un moteur qui
existe sur PyPI, pas un numéro qu'aucun `uvx` ne saurait satisfaire.

CE QUI RESTE NU, ET C'EST VOULU

Les `uv tool install dsoxlab` des README et des CONTRIBUTING : ils s'adressent
à un apprenant, qui doit prendre la dernière version. Ce sont des instructions,
pas des appels.

LE GARDE-FOU DU MANIFESTE ANNONÇAIT UN ACCORD EN ÉCARTANT UN TIERS DU DISQUE

`scripts/gen-catalogues.py --mesurer` répondait « manifeste en accord avec le
disque (12 catalogues) » quand le disque en portait DIX-NEUF. Une seule ligne,
`if labs:`, sautait en silence tout catalogue sans lab.

Le filtre se défend : `dsoxlab catalog list` n'a rien à proposer d'un catalogue
vide. Le message ne se défendait pas. Et c'est le défaut même que ce script
existait pour empêcher : la liste des catalogues avait déjà été écrite une fois
avec six entrées quand le disque en portait douze, et 901 messages avaient été
sautés sans qu'aucun contrôle le dise. Partir du disque ne suffit pas, il faut
DIRE ce qu'on en écarte.

Il nomme désormais les sept, et explique qu'ils s'inscriront dès leur premier
lab.

UN SECOND DÉFAUT QUE LE PREMIER CACHAIT

Un catalogue inscrit au manifeste qui tombait à zéro lab disparaissait de la
comparaison, donc était signalé « introuvable sur le disque : vérifie qu'il n'a
pas été renommé ». Le diagnostic envoyait chercher un renommage qui n'avait pas
eu lieu. Il dit maintenant ce qui est vrai : le catalogue est là, mais il ne
porte plus aucun lab.

DEUX CLIQUETS, PROUVÉS PAR TROIS MUTATIONS

`tests/test_socle_du_catalogue.py` refuse tout appel non borné dans ce que le
socle EXÉCUTE, et vérifie que la borne vaut la version du moteur et non une
valeur figée. Les commentaires qui citent `uvx dsoxlab` pour expliquer pourquoi
on ne l'emploie pas sont exemptés, sans quoi la justification serait impossible
à écrire.

    le CI revient à l'appel nu                 → rouge
    le hook revient au moteur du PATH          → rouge
    une borne figée au gabarit                 → rouge

Les deux premières sont les défauts exactement observés sur les sept catalogues.

VÉRIFIÉ

    pytest tests/                    1611 passed
    tests du socle                   19 passed, dont 2 nouveaux
    ruff check src/ tests/ scripts/  All checks passed
    mypy src/dsoxlab/                97 fichiers, aucune erreur
    complexite / code-mort / écran   les trois cliquets verts
    gen-catalogues.py --mesurer      nomme les 7, compare les 12
    uv lock                          0.5.1 → 0.5.2

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@stephrobert
stephrobert merged commit 7380011 into main Oct 17, 2026
20 checks passed
@stephrobert
stephrobert deleted the feat/socle-borne-le-moteur branch October 17, 2026 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant