Skip to content

feat(contrat): un état brouillon pour un lab et pour un catalogue (#369) - #372

Merged
stephrobert merged 4 commits into
mainfrom
feat/etat-brouillon
Nov 14, 2026
Merged

stephrobert merged 4 commits into
mainfrom
feat/etat-brouillon

Conversation

@stephrobert

Copy link
Copy Markdown
Owner

Summary

Closes #369. The v1 contract had no draft state. A lab was a draft only as long as it was not pushed, and 0.9.2 offered certificats, an empty repository, in catalog list.

Lab: status: draft | published in lab.yaml, published by default, so no existing catalogue changes.

Command On a draft lab
list-labs hidden; --drafts shows it, marked "(draft)" / "(brouillon)"
list-labs --json, show --json every lab carries "status": "draft" or "published" (compatible extension, documented in docs/machine-output)
next (and therefore start) skipped; not counted in remaining
course refused (exit 1), unless --drafts
progress not counted
push, export not sent; export --lab <draft> exits 1
run, check, submit, show allowed when named, with an information line (on stderr under --json)
validate-structure validates it like any lab; an unknown status value is reported
scores unchanged, by choice: it is the local history of what was played, nothing leaves the machine

Catalogue: draft: true in the packaged manifest.

  • catalog list hides a draft entry; catalog list --drafts shows it.
  • catalog list --json carries draft.
  • catalog add still works by id or by URL.
  • certificats stays in the manifest as draft: true, as the issue asks.

scripts/gen-catalogues.py:

  • a draft entry is measured, but stays out of the README table and is not a drift;
  • a non-draft entry that publishes no lab is a drift: exit 1, telling you to mark it draft or remove it. 0.9.2 had this defect: it offered an empty certificats.
  • Measured read-only on GitHub: --check exits 0, with 699 labs on 18 published non-draft repositories.

Decisions taken while implementing, to review

  • An unknown status value follows the same policy as feedback: the parser keeps it, validate-structure reports it, and the lab behaves as published. So a typo in draft publishes the lab, and only the catalogue's CI says so.
  • challenge, hint, guide, reset and clean work on a named draft, without an information line.

Type of change

  • Bug fix
  • New feature
  • Refactor
  • Documentation
  • Chore / tooling
  • Security / supply chain

Checklist

Always

  • ruff check src/dsoxlab tests tests_e2e fuzz scripts: passed
  • mypy src/dsoxlab: no issues in 123 files
  • pytest: 2,277 passed
    • New tests: tests/test_etat_brouillon.py (27), tests/test_catalogue_brouillon.py (7), plus 5 in test_gen_catalogues.py.
    • Played against a git archive of origin/main: 32 fail, 12 pass.
    • The 12 that pass are the 7 pre-existing generator tests, 2 deliberate counter-examples and 3 behaviours that were already right in 0.9.2.
    • Among the new tests, the issue's own requirement: a draft lab never appears in next, progress or a push.
  • pytest tests_e2e: 18 passed
  • complexite.py --verifier and complexite-ecran.py --verifier: stable. progress went over the threshold and was brought back down without refreezing.
  • Domain-agnostic: test_le_moteur_ne_code_aucun_nom_de_catalogue passes
  • Manually tested on two lab repositories: not done; this relies on tests and a trial catalogue

When behavior changes

  • CHANGELOG.md and CHANGELOG.fr.md: [Unreleased], Added and Fixed, to ship in 0.9.3
  • Version: bumped at release time (0.9.3)

When a command or option is added, removed or changed

  • i18n keys in EN and FR
  • help=_() and fullhelp in EN and FR for the three new options: list-labs --drafts, course --drafts and catalog list --drafts
  • The new log lines are in English

When .github/workflows/ is touched

N/A.

When the declarative contract changes

  • docs/contract-v1(.fr).md: field, default value and a per-command table. schemas/lab.schema.json updated (there is no manifest schema).
  • Fuzz: seed fuzz/corpus/lab_yaml/status-draft.yaml, plus dictionary entries
  • A malformed value (a list) does not crash the parser: it is turned into a string and reported, as for feedback

Left open: the lab catalogues' CLAUDE.md files (not versioned), and the JSON of catalog list in docs/machine-output, where that command was never documented.

🤖 Generated with Claude Code

stephrobert and others added 4 commits November 14, 2026 11:40
Un lab poussé sur main pour être partagé devenait visible comme s'il était
fini, et un catalogue sans lab publié était proposé par `catalog list`.

Lab : `status: draft | published` dans lab.yaml, `published` par défaut.
Un brouillon quitte list-labs (sauf --drafts, où il est marqué), next et
start, course (sauf --drafts), progress, l'export et push. run, check,
submit et show l'acceptent par son identifiant, avec une ligne qui dit que
c'est un brouillon. validate-structure le valide comme les autres et
signale une valeur inconnue, qui se comporte comme `published` (même
politique que `feedback`). scores ne change pas : historique local.
`status` est exposé dans le lab de --json.

Catalogue : `draft: true` au manifeste packagé. catalog list et l'accueil
ne le proposent plus (catalog list --drafts le montre), catalog add
l'installe toujours. certificats repasse en brouillon.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…un lab

La 0.9.2 mesurait certificats à zéro lab, l'écartait de la table du
README, et laissait catalog list le proposer quand même. Une entrée sans
`draft` qui ne publie aucun lab est désormais un écart (sortie en 1), avec
un message qui dit de la passer en `draft: true` ou de la retirer.

Une entrée en brouillon est mesurée, reste hors de la table même avec des
labs, n'est jamais un écart, et n'est pas signalée comme dépôt public
oublié. Mesuré le 2026-11-14 sur GitHub : `--check` sort en 0, 699 labs sur
18 dépôts publiés hors brouillon, certificats en brouillon à 0 lab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… publié

contract-v1 (EN et FR) : le champ `status`, sa valeur par défaut, son
effet commande par commande, la politique d'une valeur inconnue, et le
`draft: true` du manifeste. machine-output (EN et FR) : le champ `status`
de l'objet lab, extension compatible. CHANGELOG EN et FR : section
[Unreleased], sans bump de version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	CHANGELOG.fr.md
#	CHANGELOG.md
@stephrobert
stephrobert merged commit 13391ca into main Nov 14, 2026
20 checks passed
@stephrobert
stephrobert deleted the feat/etat-brouillon branch November 14, 2026 11:03
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.

feat(contrat): un état brouillon pour un lab et pour un catalogue

1 participant