docs(par-public): trois portes, et des chemins que le code confirme (0.1.63) - #154
Merged
Conversation
…0.1.63) Toute la documentation tenait dans deux README qui parlaient en même temps à l'apprenant, à l'auteur de catalogue et au formateur. Aucun des trois n'y trouvait son chemin, et certaines sections décrivaient un produit qui n'existe pas. Les affirmations fausses, chacune vérifiée contre le code : - `~/.local/share/dsoxlab/progress.db` et `~/.config/dsoxlab/config.yaml` n'existent nulle part. La base est `<catalogue>/.dsoxlab.db`, une par catalogue, et aucun fichier de configuration utilisateur n'est lu. - « une base SQLite locale conforme à la spécification XDG » : elle est dans le catalogue, précisément pour que la progression le suive. - `incus` et `kvm` annoncés comme des runtimes. Il y en a deux, `shell` et `vm` ; le backend vient de `meta.yml: infra.provider`, pas du lab. - une carte d'architecture nommant `IncusRuntime` et `KvmRuntime`, deux classes qui n'existent pas. - un `runtime.host` dans l'exemple de `lab.yaml` le plus en vue, champ qu'aucun code ne lit, et que le contrat documente comme un piège. - l'aide de `--lab-home` nommait « le dépôt linux-training » comme s'il était le seul catalogue, dans les deux langues. Le contrôle qui empêche la dérive de recommencer étend le mécanisme existant plutôt que d'en ouvrir un second : `scripts/generer-doc.py`, qui produisait déjà la table des commandes depuis la CLI, relève maintenant les emplacements réels **en appelant les fonctions que la CLI appelle**, sur un HOME jetable, et refuse tout chemin qu'une page cite et que le code ne produit pas. Prouvé par mutation : réintroduire `progress.db` dans un README rend deux tests rouges. Un chemin peut être cité pour dire qu'il n'existe pas, mais par la seule page dont c'est le sujet, et un test vérifie l'autre bout : le jour où #78 rendra `config.yaml` réel, la page qui l'annonce absent deviendra fausse, et le test le dira. Les pages, chacune nommant son public en tête : apprenant, auteur de catalogue, formateur, plus deux références communes (où dsoxlab écrit, les commandes). Les deux README restent la porte d'entrée et se lisent en trente secondes. Aucun générateur de site n'est introduit : cette décision appartient au propriétaire du dépôt. Closes #86
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Toute la documentation tenait dans deux README qui parlaient en même temps à
l'apprenant, à l'auteur de catalogue et au formateur. Aucun des trois n'y
trouvait son chemin, et certaines sections décrivaient un produit qui
n'existe pas.
Ce qui était faux, et la preuve pour chacun
~/.local/share/dsoxlab/progress.dbgit grep progress.db -- src/: rien.sessions/store.py:10→.dsoxlab.db, une base par catalogue~/.config/dsoxlab/config.yamlgit grep 'config.yaml|XDG_CONFIG' -- src/: rien. C'est la cible de #78, pas un chemin luincusetkvmprésentés comme des runtimesruntimes/manager.py:SHELL → ShellRuntime,VM/KVM/INCUS → VmRuntime. Deux runtimes ; le backend vient demeta.yml: infra.providerIncusRuntimeetKvmRuntimegrep '^class ' runtimes/*.py: ces classes n'existent pasruntime.hostdans l'exemple delab.yamlmodels/lab.pyne parse queruntime.targets[].host: le champ est ignoré en silence--lab-home: « Racine du dépôt linux-training »validate-structurevérifie que chaque lab référencé existe »discover_labs(): un lab déclaré mais absent passe sans un motDeux emplacements réels n'étaient documentés nulle part :
~/.cache/dsoxlab/<id>/(inventaire et
ssh_config) et~/.ssh/config.d/<id>.conf. Ils le sont.Les trois portes
docs/README.mdaiguille ;learner.md(installer, choisir, jouer, lire sanote),
catalog-author.md(contrat, schémas, validators, pièges) ettrainer.md(infrastructure, providers, comptes, snapshots) nomment leur publicen tête.
files.md(où dsoxlab écrit) etcommands.md(table générée) sont laréférence commune. Chaque page existe en EN et FR.
Les deux README passent de 460 et 423 lignes à 150 : quoi, installer, jouer,
puis les trois portes. La carte d'architecture, corrigée, rejoint
CONTRIBUTING,son vrai public.
Le contrôle qui empêche la dérive de recommencer
C'est le cœur de l'issue : sans lui, cette PR répare une fois et le problème
revient. Il étend le mécanisme existant (
scripts/generer-doc.py, déjà jouépar le hook pre-commit) plutôt que d'en ouvrir un second à maintenir.
Il relève les emplacements réels en appelant les fonctions que la CLI
appelle (
store.record_hint,config.set_active_lab,terraform.workdir,inventory.*_path,locking.lock_path,logging_setup.chemin_journal,demo.destination,update_check.cache_path) dans un sous-processus auHOMEjetable, puis regarde ce qui a réellement été créé. Un chemin cité par une page
doit correspondre.
Une page peut citer un chemin pour dire qu'il n'existe pas, mais la dispense
est nominative : elle nomme la page autorisée. Une dispense globale aurait
rouvert la porte. Et
absents_devenus_reels()tient l'autre bout : le jour où#78 rendra
config.yamlréel, le test exigera la mise à jour de la page quil'annonce absent.
Il a servi le lendemain de sa pose
Au rebase sur la 0.1.62, il a signalé tout seul :
Exact : #90 venait de retirer l'écriture du wrapper. Les pages disent désormais
qu'il n'est plus écrit, ce qui a son utilité pour qui en a un qui traîne d'une
version ancienne, et le chemin rejoint la dispense nominative. C'est la première
dérive attrapée par le contrôle, un jour après son existence.
Type of change
Checklist
Always
uv run ruff check src/dsoxlab tests tests_e2e fuzz scripts— All checks passed!uv run mypy src/dsoxlab— no issues in 60 source filesuv run pytest— 620 passed ;tests_e2e— 16 passedlinux-trainingest corrigéeWhen behavior changes
uv.lockrégénéréWhen a command or option is added, removed or changed
opt_lab_home,fullhelp_runtimes, la lignerun <id>) : elles décrivaient elles aussiun produit qui n'existe pas, et la documentation les aurait contredites.
When
.github/workflows/is touched — N/AWhen the declarative contract changes — N/A
Mutation
Réintroduire
~/.local/share/dsoxlab/progress.dbdansREADME.mdfait rougirtest_aucune_page_ne_cite_un_chemin_inexistant, en nommant la page et lechemin ; restauré, tout repasse. La mutation est gelée en test permanent
(
test_le_controle_refuse_les_chemins_de_l_issue_86), qui rejoue les troislignes fausses de l'issue.
Deux décisions qui te reviennent
Documentationpointe désormais surdocs/README.mddans le dépôt, au lieu del'index générique d'un blog. Recommandation : garder ce Markdown comme source
unique et, si un site est voulu, publier ces mêmes fichiers via MkDocs Material
sur GitHub Pages (aucune réécriture, un workflow), plutôt qu'un générateur qui
imposerait son arborescence.
Homepagereste le blog : l'issue ne visait queDocumentation.docs/commands.md. La pagePyPI perd donc la liste et gagne un lien. Si tu la veux de retour dans le
README, c'est une ligne de configuration du générateur.
Un bruit confirmé deux fois
tests/test_services.py::test_deux_services_se_joignent_par_leur_nomettest_post_start_execute_vraiment_dans_le_conteneursont instables souscharge, observés indépendamment sur cette branche et sur #153. Ils dépendent de
vrais conteneurs Docker, et rien ici n'y touche. Une issue les suit.
Related issues
Closes #86
Voisine de #120, déjà livrée.
~/.config/dsoxlab/config.yamlest décrit commeà venir (#78), pas comme existant.
🤖 Generated with Claude Code