Skip to content

feat(json): dix commandes, un document, et un verdict qui se lit sans traduire (0.1.65) - #157

Merged
stephrobert merged 1 commit into
mainfrom
feat/interface-machine
Aug 24, 2026
Merged

feat(json): dix commandes, un document, et un verdict qui se lit sans traduire (0.1.65)#157
stephrobert merged 1 commit into
mainfrom
feat/interface-machine

Conversation

@stephrobert

Copy link
Copy Markdown
Owner

Une intégration pouvait lire un quart de ce que l'outil sait. Pour le reste, il
lui fallait analyser des tableaux Rich dont la largeur suit celle du terminal,
et dont les libellés changent avec DSOXLAB_LANG. Cette PR solde l'écart :
dix commandes rendent désormais un document, et un verdict se lit sans le
traduire.

Ce qui change

show, scores, next, doctor et validate-structure rejoignent
list-labs, progress, check, status et support. Toutes passent par
machine.emit(), donc toutes portent leur schema.

Le point de conception est la séparation de la clé et du libellé. doctor
donne à chaque contrôle une key stable (kvm, pytest, libvirt_pool…) et
un state énuméré (ok, failed, choice_required) ; validate-structure
fait de même pour chaque signalement. Le label, lui, reste traduit. C'est ce
qui permet d'annoncer kvm à un programme et « Terraform » à un humain, sans
demander au programme de deviner la langue de son interlocuteur :

$ DSOXLAB_LANG=en dsoxlab doctor --json | jq '.required[0]'
{ "key": "python", "state": "ok", "ok": true, "label": "Python", … }

$ DSOXLAB_LANG=fr dsoxlab doctor --json | jq '.required[0]'
{ "key": "python", "state": "ok", "ok": true, "label": "Python", … }

Les clés et le state sont identiques dans les deux langues. Vérifié sur les
deux, pas déduit du code.

docs/machine-output.md et sa version française décrivent le contrat : ce que
porte chaque document, ce qui est stable, et la règle de tolérance attendue d'un
consommateur (une valeur inconnue se traite comme inconnue, pas comme une
erreur).

Contrôles joués

Always

  • uv run ruff check src/dsoxlab tests tests_e2e fuzz scripts : All checks
    passed
  • uv run mypy src/dsoxlab : no issues found in 60 source files
  • uv run pytest : 646 passed (629 avant, +17)
  • uv run pytest tests_e2e : 18 passed sur la roue construite et
    installée
  • Le moteur reste neutre vis-à-vis du domaine. Les occurrences de
    terraform et kvm ajoutées à doctor.py sont des noms
    d'exécutables
    que l'outil pilote et les clés stables des contrôles
    correspondants, jamais une catégorie de labs : aucun if category == …
    n'apparaît dans le diff
  • Aucun chemin personnel, aucun hôte en dur
  • Testé sur deux dépôts fournisseurs, dont celui qui attrape les
    régressions d'agnosticisme :
    - terraform-training (aucun bloc infra:, 87 labs tous shell) : les
    cinq commandes neuves rendent leur document, et doctor ne réclame
    aucun composant d'infra
    - ansible-training (113 labs, runtime vm) : doctor classe kvm,
    terraform, ansible et libvirt_pool en requis, et incus en
    informatif

When behavior changes

  • CHANGELOG EN et FR ; version 0.1.65 dans pyproject.toml ;
    uv.lock aligné

When a command or option is added, removed or changed

  • Clés ajoutées dans i18n/strings/en.py et i18n/strings/fr.py
    (+40 et +41 lignes)
  • help=_("…") et la section fullhelp_commands mis à jour dans les deux
    langues
  • Joué sous DSOXLAB_LANG=en et DSOXLAB_LANG=fr : le rendu humain reste
    traduit, le document machine ne bouge pas

When .github/workflows/ is touched — N/A

Aucun fichier de .github/workflows/ n'est touché par ce diff.

When the declarative contract changes — N/A

Ni meta.yml ni lab.yaml ne gagnent de champ : la PR expose ce que le moteur
sait déjà, elle ne lui demande rien de nouveau.

Un choix à connaître

Sur une erreur dure (identifiant de lab inconnu, meta.yml illisible, contexte
absent pour next), la sortie standard reste vide, la cause part sur la
sortie d'erreur et le code de sortie porte le verdict. json.loads(stdout)
fonctionne donc sans rien retirer, au prix d'un cas où il n'y a rien à charger.
Le comportement est documenté dans docs/machine-output.md, il n'est pas
implicite.

Related issues

Closes #83

🤖 Generated with Claude Code

… traduire (0.1.65)

`--json` couvre désormais toutes les commandes dont la sortie a une structure :
`show`, `scores`, `next`, `doctor` et `validate-structure` rejoignent
`list-labs`, `progress`, `check`, `status` et `support`. Tout passe par
`machine.emit()`, donc tout porte `schema`.

Le point qui demandait un choix, ce sont les verdicts. Recopier la phrase
affichée dans un champ aurait donné une interface d'apparence complète et
inutilisable : personne ne peut savoir si c'est vert ou rouge sans analyser du
français ou de l'anglais. Chaque contrôle de `doctor` porte donc une `key`
stable et un `state` en jeton, chaque anomalie de `validate-structure` la `key`
de la règle qui a parlé ; le libellé traduit est posé à côté, pour les yeux. Un
test joue `doctor --json` dans les deux langues et exige des clés et des états
identiques là où les libellés diffèrent.

Le code de retour, lui, ne bouge pas : `--json` change la forme de la sortie,
jamais le verdict. `doctor --json --fix` est refusé, parce que la sortie d'apt
précéderait le document.

Au passage, une sonde qui ne répond pas ne fait plus tomber le diagnostic :
`virsh version` sur un hôte dont libvirt se tait levait une `TimeoutExpired`
qui emportait toute la commande, et depuis que `doctor --json` est une
interface, elle emportait aussi le document de l'appelant.

Documentation : `docs/machine-output.md` et sa version française décrivent
chaque document champ par champ, les codes de retour, et la règle d'évolution.
Le `fullhelp` a gagné la section correspondante dans les deux langues.

Closes #83.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@stephrobert
stephrobert merged commit d3bcdf2 into main Aug 24, 2026
18 checks passed
@stephrobert
stephrobert deleted the feat/interface-machine branch August 24, 2026 08:42
stephrobert added a commit that referenced this pull request Aug 24, 2026
Le merge de #157 a posé 0.1.65 sur main. Les seuls conflits sont la ligne de
version et l'ordre des deux sections du CHANGELOG, résolus en gardant 0.1.66
au-dessus de 0.1.65. Le contenu obtenu est identique à celui d'un rebase joué
séparément et validé sur 650 tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

[P1] Étendre --json aux commandes qui en manquent et documenter l'interface machine

1 participant