L'usine logicielle Playlab42#
Une usine logicielle n'est pas une liste d'outils. C'est un chemin cohérent de la demande jusqu'à une livraison vérifiée, avec des conventions partagées, des contrôles fiables et un retour sur ce qui fonctionne ou reste difficile.
Playlab42 en fournit une version pédagogique : une application 100 % statique, Docker pour développer, OpenSpec pour clarifier les besoins, skills et kit pour contribuer, GitHub Actions pour vérifier, GitHub Pages pour publier. Il n'est pas nécessaire d'ajouter Kubernetes, un backend ou une plateforme d'orchestration pour bénéficier de ces pratiques.
Ce guide décrit le code versionné et les réglages observés le 4 octobre 2026. Une correction préparée dans une branche n'est disponible en production qu'après livraison ; un fichier de workflow ne constitue pas une preuve d'exécution réussie.
Livraison constatée et correctifs locaux#
Les lots 3 à 5 sont intégrés à main et publiés : la
PR #144 a été fusionnée le
3 octobre 2026 à 18:24:44 UTC, au commit
283b1cb359ef3363c7f70ef7fa0aef57a93ddc11. Le
run de publication 37144090802
et le run de sécurité 37144090475
ont réussi sur ce commit. Cette preuve concerne cette livraison, pas les
modifications ultérieures du worktree fix/review-software-factory.
Les correctifs de revue des builders, de préservation des images OG et du mode
d'écriture atomique sont intégrés à main et publiés via la
PR #145, fusionnée le 3 octobre
2026 au commit 8a643e8adf051d2ed92aee4ed40dd6ae0f574611. Elle ajoute aussi un gate
sur Build, déjà requis, exigeant le succès de Security lint et de Trivy
HIGH/CRITICAL via un workflow réutilisable partagé ; un gate ignoré ne doit
pas autoriser la suite. La
publication 37148586787
et l'audit 37148586535
ont réussi sur ce commit. Les neuf checks GitHub requis restent le réglage
actuellement observé ; aucune mutation distante n'est impliquée.
Validation native constatée le 3 octobre 2026, head a5598b2 :
CI 37148235271
et Security Audit 37148235235
réussis : 100 suites / 2 124 tests, seuils ciblés, lint, types, Trivy,
double fabrication/reprise et 64 interactions Chromium. L'upload Codecov
a réussi, mais il reste non bloquant. Cette preuve datée concerne ce head
fusionné ; chaque PR suivante doit vérifier les checks de sa propre tête.
La suite qualité proposée
part de cette branche de revue. Après sa fusion squash, sa branche de plan
a été réalignée sur main après vérification d'égalité des sources, pour ne pas
réintroduire les correctifs dans une nouvelle pile. La PR #146 décrivait la proposition, reprise dans quality/tests-first
avec tests de comportement avant refactoring. La
PR #147 est maintenant
intégrée à main et publiée, au commit
611a29bebe6409f5fb0e59413ff35f3d03751f92. La
publication 37153902594
et l'audit 37153902484
ont réussi. Le plan #146 est fermé comme remplacé ; les preuves de la
dernière tête et de la livraison sont détaillées dans le guide qualité.
La suite quality/core-refactors a livré les corrections du cœur par priorité :
contrats moteurs et déterminisme, puis refactorings et mutualisations ciblées.
La PR #148 est intégrée à main ef0a2aa et publiée
(run 37162681481).
La continuation quality/duplication-complexity est livrée via la PR #149,
au commit 72a8f5d : refactorings mesurés et rapport explicite de
duplication/complexité. La publication 37199116572
et l'audit 37199116386
sont réussis. Le rapport de ce main contient encore six fonctions de production
JS/HTML > 20. La suite quality/rendering-audio est maintenant livrée via
la PR #150 au commit d4c55d2 :
publication 37205096915
et audit 37205096724
réussis. Il reste 53 fonctions JS/HTML > 10, aucune > 20, et 58 clones.
quality/artifact-pipeline a livré cette simplification via la PR #151
sur main a54954c : publication 37209561127
et audit 37209560905
réussis, 49 fonctions > 10 et 58 clones.
quality/application-contracts est livrée via la PR #152 sur main 5956cd9 :
publication 37218066993
et audit 37218066738
réussis, 0 fonction >10 et 56 clones. Elle ajoute des budgets
de production bloquants pour Build et un smoke Chromium/Firefox/WebKit dans le
check Browser existant ; les détails et limites restent dans le
bilan applicatif.
La continuation quality/semantic-deduplication consolide uniquement les clones
ayant un contrat réellement commun, après caractérisation ; elle n'est pas livrée.
Carte de l'usine#
| Étape | Brique Playlab42 | Preuve / décision |
|---|---|---|
| Comprendre | Demande, specs existantes, exploration | Périmètre et contraintes explicites |
| Spécifier | OpenSpec/OPSX : proposal, specs, design, tasks | Scénarios observables et autorisation d'implémenter |
| Préparer | AGENTS.md, skills et scaffold | Conventions communes, module et manifests valides |
| Réaliser | HTML/CSS/JS, TS optionnel, composants partagés | Diff ciblé et tests du comportement |
| Vérifier | Docker, Jest, types, lint, navigateur, OpenSpec | Résultats réels, pas cases cochées par anticipation |
| Relire | PR, CI et humain | Décision de merge distincte du succès des tests |
| Publier | CI réutilisée, archive testée et Pages | Même commit et même artefact |
| Contrôler | build-info.json, smoke HTTP | Identité et ressources effectivement accessibles |
| Capitaliser | Docs, retour d'expérience, sync/archive | Livraison constatée et décision explicite |
OpenSpec et agents : les bonnes frontières#
OpenSpec 1.14.0 est un CLI local épinglé, exécuté dans Docker. Le schéma
spec-driven organise quatre artefacts ; les tâches dépendent des specs et du
design, mais les travaux indépendants peuvent avancer en parallèle.
Les six skills openspec-* et cinq skills métier playlab-* vivent dans
.github/skills/. Le lien .claude/skills expose la même source à Claude.
Il ne crée pas de commandes /opsx:*. Le skill officiel openspec-propose
s'arrête à la planification ; l'implémentation demande l'autorisation prévue.
Ne pas régénérer les intégrations avec init --force ou update dans le dépôt.
Un skill est une procédure de travail, pas un droit d'accès ni un moteur d'exécution. Il ne donne pas l'autorisation de pousser, merger, publier ou archiver. Il ne remplace ni une revue humaine ni une observation navigateur. Lire le workflow OPSX et les skills de projet pour les procédures détaillées.
Le chemin recommandé pour contribuer#
Le kit est un chemin de démarrage réutilisable (« golden path »), pas une obligation de produire un module complexe. Exemple illustratif :
make info
make openspec-list
make scaffold TYPE=tool ID=hello-usine TITLE="Hello usine"
make npm CMD="run build:local"
make serve
hello-usine n'est pas livré par ce guide. Avant de générer un module qui change
le comportement, préparer le change OpenSpec et consigner le périmètre autorisé.
Puis personnaliser le code, les manifests et les tests, observer le résultat,
ouvrir une PR et suivre les décisions humaines.
Quand peut-on dire « terminé » ?#
- Le code et les contenus répondent aux scénarios demandés.
- Les tests pertinents passent ; les validations non exécutées sont signalées.
- Les erreurs restent visibles, les thèmes et contrôles clavier sont utilisables.
- Les guides et sources de référence sont cohérents avec le changement.
- La PR indique les résultats, risques et limites ; un succès local n'est pas annoncé comme une CI GitHub réussie.
- « Préparé », « commité », « PR ouverte », « mergé » et « publié » sont des états différents. L'archive OpenSpec attend la livraison et une décision explicite.
Les garanties automatisées#
CI et publication livrées#
Sur une PR, ci.yml sélectionne les contrôles applicables : lint qualité et sécurité JS ciblée, rapport Code quality
(duplication et complexité), Jest/coverage, types, audit npm requis, validation OpenSpec stricte,
build et navigateur. Sur push main, deploy.yml appelle cette même CI dans
son run et attend son succès avant publication. Un lancement manuel hors main
échoue explicitement.
Le build inclut TypeScript, les bibliothèques runtime, les catalogues, les guides
et le packaging public site/. L'archive github-pages est testée dans Chromium
sans reconstruction, puis publiée telle quelle. La sortie publique exclut
les dépendances npm, tests, caches et configurations d'agents. Les fichiers
réservés au dépôt sont accessibles par les liens GitHub du lecteur documentaire.
CI sélective et rebases#
Le workflow reste déclenché sur chaque PR, avec les mêmes neuf noms de checks
requis. Le job Impact classe le diff entre la base et le commit de merge
effectivement testé ; un renommage examine les deux chemins. Aucun
paths-ignore global ni continue-on-error ne transforme une analyse nécessaire
en contrôle facultatif.
| Changement | Parcours |
|---|---|
Markdown connu dans docs/, openspec/, les skills, ou README/AGENTS/CLAUDE racine | Contrats documentaires ciblés, fabrication, guides navigateur et smokes multi-moteurs ; validation OpenSpec si concernée |
| HTML, JS ou TS d'un jeu, outil ou slide | Tests complets et contrôles applicables ; les slides restent exécutables |
| CSS local | Tests, rapport qualité et navigateur ; pas de vérification de types ou de scripts inchangés |
| Code partagé, fabrication, dépendances ou configuration | Tous les contrôles |
| Chemin inconnu, diff indisponible ou Markdown contenant du HTML | Parcours complet conservateur, avec motif explicite |
La détection du HTML est volontairement conservatrice, y compris dans les
exemples Markdown. Un README de jeu non classé explicitement reste dans le
parcours complet. Les contrats documentaires sont listés dans
scripts/ci-plan.js ; ils ne produisent pas de faux rapport de couverture complète.
Les floors Jest et budgets qualité restent inchangés.
Pour un rebase, le diff de PR reste souvent du code. La réduction des relances vient alors des empreintes, pas du seul classement par chemins. Une preuve originale d'un run CI réussi de la même PR peut être réutilisée si ses entrées Git, workflow, configuration, Node exact et image de runner sont identiques. L'ancien commit est récupéré et ses empreintes recalculées : ni un cache npm, ni le SHA de la branche, ni une empreinte simplement déclarée ne suffit. Les preuves réutilisées ne sont pas elles-mêmes réutilisables.
Jest tient compte de toute la documentation, car des tests la lisent. Un changement
documentaire peut donc imposer son exécution complète sur une PR de code.
Pour Browser, la preuve réutilisée concerne les interactions applicatives :
la nouvelle archive, les guides et les smokes sont toujours contrôlés.
Le résumé distingue execute, documentation, not-applicable et reused,
avec le run, la tentative et le commit d'origine. Les rapports détaillés d'une
analyse réutilisée restent dans ce run, sans nouvelle provenance fictive.
Les preuves ci-plan et ci-evidence-RUN-TENTATIVE sont conservées 30 jours.
La recherche est bornée aux 30 derniers runs de la branche, dont trois candidats
réussis au maximum. Une preuve absente, expirée, invalide ou inaccessible
provoque une nouvelle exécution ; les erreurs d'accès sont signalées.
Les forks sans preuve admissible exécutent les contrôles nécessaires.
Build et l'agrégateur intégré au check Browser requis refusent les amonts échoués, annulés, ignorés ou
manquants. Sur main et en lancement manuel, la CI reste complète, sans
réutilisation. Les audits npm, Trivy et Gitleaks, ainsi que l'audit quotidien,
restent exécutés : les bases de vulnérabilités et l'historique ne sont pas des
entrées figées. Les runs CI de PR devenus obsolètes sont annulables ; les
publications en cours ne sont pas interrompues.
Identité et contrôle après publication#
build-info.json indique la version et le SHA CI. Le smoke test HTTP compare
ce SHA et contrôle dix ressources HTTP, distinctes des neuf checks GitHub
requis. Le manifeste est la dixième ressource ajoutée au contrat de smoke :
il vérifie l'identité et les empreintes lockfile/snapshot attendues, pas tous
les hashes des fichiers distants.
| Ressource contrôlée | Rôle |
|---|---|
build-info.json | Version et commit publiés |
build-manifest.json | Identité et empreintes des entrées attendues |
index.html | Portail |
docs/site/index.html | Lecteur documentaire |
data/catalogue.json | Catalogue des outils et jeux |
data/parcours.json | Catalogue des parcours |
data/bookmarks.json | Catalogue des bookmarks |
catalogue.tools[0].path | Point d'entrée du premier outil |
catalogue.games[0].path | Point d'entrée du premier jeu |
${epic.path}/slides/${slide.id}/index.html | Première slide du premier parcours |
Une erreur finale rend le workflow rouge, mais ne retire pas le site déjà publié. Cette identité n'est pas une provenance signée ni une attestation SLSA.
Ce qui reste distinct#
- La validation OpenSpec vérifie la structure des exigences, pas le code.
- Les tests navigateur couvrent un socle d'interactions dans Chromium, pas tous les navigateurs, contenus, inférences ML ou qualités audio.
- Le build normal utilise le snapshot OG versionné ; le refresh éditorial est explicite. Deux fabrications et les empreintes sont comparées en CI. Le manifeste/SBOM et la reprise locale sont décrits dans le runbook, sans signature ni garantie hermétique.
- L'audit npm au seuil modéré et le lint sécurité JS ciblé sont requis par la CI de livraison. Le workflow complémentaire reste séparé : Gitleaks et Trivy HIGH/CRITICAL peuvent échouer, Hadolint et les heuristiques lint restent consultatifs. Le rapport distingue les états des jobs, pas « aucun problème » lorsqu'un résultat manque. Aucun rapport ne garantit l'absence de défaut.
- Les seuils Jest ciblent SeededRandom, packaging, smoke, portail, moteurs et Simulation ; il n'y a pas de seuil global ni de contrôle bloquant universel du code modifié. L'envoi Codecov est non bloquant. Voir le guide qualité et son plan.
- Sur autorisation ultérieure, une protection classique de
maina été activée et relue via l'API : PR et neuf checks natifs requis, y compris pour l'admin. Il n'y a pas encore d'approbation indépendante obligatoire, faute de second reviewer habilité. Voir le réglage précis.
Voir les pipelines (source Markdown), les tests et le déploiement.
Aller plus loin : ce qui manque encore#
Cette liste est une feuille de route, pas une promesse de fonctionnalités déjà livrées. Les priorités sont adaptées à un support de formation.
| Priorité | État / point restant | Évolution utile et critère observable |
|---|---|---|
| Haute | main protégée : PR et neuf checks requis ; noms constatés sur la PR #135 | Ajouter un second reviewer, exiger une approbation et vérifier les noms après évolution du pipeline |
| Haute | npm et lint sécurité JS ciblé requis ; Trivy et Gitleaks séparés ; heuristiques consultatives | Trier les diagnostics, étendre les gates justifiés et revoir les exceptions datées ; pas de faux succès |
| Moyenne | Seuils ciblés et complexité critique, pas sur tout le code | Étendre progressivement aux moteurs et modules partagés, puis contrôler le code modifié avec des tests de comportement |
| Moyenne | Actions SHA, images digest et binaires scanners vérifiés dans le lot 2 ; bases/paquets OS évolutifs | Maintenir ces références avec Dependabot ; isoler ensuite les sources de variabilité du build |
| Moyenne | Snapshot OG séparé du build ; refresh éditorial explicite | Relire ses changements, suivre les métadonnées absentes et conserver les preuves de reproductibilité |
| Moyenne | Pas de prévisualisation de PR publiée | Donner aux reviewers une URL temporaire, sur une origine adaptée, sans secrets ni privilèges de production |
| Moyenne | Smoke de publication réussi, workflow de monitoring quotidien intégré et reprise locale exercée | Constater séparément un run planifié, vérifier les notifications et définir responsable/cadence ; décider humainement d'une reprise en production |
| Progressive | SBOM de fabrication et manifeste hashé non signé | Ajouter une attestation signée de l'archive sur autorisation ; ne pas annoncer de niveau SLSA sans conformité vérifiée |
| Progressive | Retour d'expérience peu instrumenté | Mesurer durée des checks, délai de première contribution, erreurs récurrentes et livraison ; choisir peu d'indicateurs utiles |
| Progressive | Scénarios d'évaluation des skills partiels | Comparer des demandes identiques sur environnements isolés, conserver les preuves, compléter les cas non testés sans revendiquer un gain statistique |
Les premiers chantiers ne nécessitent aucun nouvel outil lourd : des réglages GitHub, des tests, une documentation fiable et un runbook peuvent suffire. Les évaluations légères de skills existent déjà ; il s'agit de les compléter, pas de prétendre qu'elles sont absentes.
Mesurer sans transformer les métriques en objectifs#
DORA décrit aujourd'hui cinq métriques : délai du changement jusqu'en production, fréquence des déploiements, temps de récupération d'un déploiement échoué, taux d'échec des changements et taux de déploiements de reprise. Elles servent à améliorer une même application au fil du temps, pas à classer des personnes ou à exiger plusieurs publications quotidiennes d'un laboratoire.
Pour Playlab42, commencer par les frictions d'atelier : démarrage Docker, premier module catalogué, erreurs de manifests, temps d'attente des checks. Ajouter uniquement les mesures qui guident une amélioration concrète, sans collecter les données personnelles des apprenants par défaut.
Fondements et sources#
Recherches consultées le 3 octobre 2026 :
- DORA — Continuous delivery : livrabilité continue, retours rapides, tests et déploiements fiables.
- DORA — Five software delivery metrics : mesurer les résultats et éviter les objectifs détournés.
- CNCF — Platform Engineering Maturity Model : capacités partagées, parcours utilisateur et amélioration comme produit.
- SLSA 1.2 — Build track : identité/provenance, puis garanties croissantes de chaîne de construction.
- GitHub — Secure use : permissions minimales, références immuables et maintenance des workflows.
- GitHub — Artifact attestations : établir et vérifier l'origine d'un artefact.
La source commune des conventions reste AGENTS.md (source Markdown). Ce guide n'est ni un audit de vulnérabilités, ni une certification, ni une preuve de CI native ou de publication de la branche en cours.