Constitution¶
Les règles non négociables de ce dépôt et du produit qu'il livre. Une règle ne figure ici que si elle est opposable : quelque chose la refuse mécaniquement, ou son absence d'applicateur est déclarée.
Comment lire ce document. Trente articles tiennent en une page ; ils suffisent à travailler.
Sous chacun vit sa jurisprudence : les décisions d'architecture qui l'ont produit, une par cas,
dans dev-docs/decisions/. On lit les articles ; on ne descend dans les cas que lorsqu'on en a
besoin. Chaque ADR déclare son article en en-tête, et un garde refuse celle qui n'en déclare pas.
Un numéro manque, et c'est voulu. La numérotation saute de A26 à A28. A27 existe dans la ligne d'où vient cette constitution : il interdit un renvoi qui ne résout que dans un dépôt disparu, ce qui n'a pas d'objet ici, où les renvois résolvent. Le numéro n'est pas réattribué : une ADR cite un article par son numéro, et un numéro qui change de sens est pire qu'un numéro absent.
Ce que la jurisprudence a révélé. Deux articles n'ont produit aucune décision : la mutation qui mesure dès qu'un comportement est complet (A8), et l'interdiction de supprimer un avertissement (A10). Tous deux disent comment on travaille plutôt que ce que le produit fait, et tous deux vivaient dans un fichier exclu du dépôt jusqu'à #4335. La mesure est rappelée ici plutôt que tue : un article que rien ne tient est une dette, pas une règle.
A1 en est sorti, et aucun compte n'est plus cité ici. La preuve qui précède l'affirmation
figurait dans cette liste ; quatre décisions la tiennent désormais. Ce paragraphe annonçait aussi
« 194 ADR » et « vingt-trois articles », deux nombres qui ne portaient rien : l'argument est le même
qu'ils vaillent 194 ou 278, et le second n'était que le complément du premier. Ils avaient vieilli en
silence, parce qu'un nombre plus petit que la réalité ne cloche pas dans une phrase. Ce qui reste est
ce qui compte, une liste nommée, et scripts/methode/matrice-constitution.py refuse qu'elle
diverge de la mesure (issue #5180).
Titre I : la preuve¶
A1 : La preuve précède l'affirmation¶
Aucune affirmation d'achèvement sans preuve fraîche. La commande a été lancée dans ce fil, sa sortie a été lue, son code de sortie vérifié. Sauter une de ces étapes, c'est affirmer, pas vérifier.
A2 : Un garde est vu rouge sur sa propre mutation¶
Un dispositif vert n'est pas un dispositif vérifié. Avant de lui faire confiance, on casse à la main exactement ce qu'il prétend attraper, et on le regarde rougir. Après toute réécriture du garde ou de son sujet, on refait la mutation. Un garde qui ne peut pas rougir s'ancre autrement, et un détecteur textuel s'exclut de son propre corpus.
A3 : Un dispositif dit ce qu'il couvre, et ce qu'il n'a pas pu lire¶
Un garde déclare la couverture qu'il a, et distingue l'état qu'il tient de celui qu'il emprunte. Une mesure dit ce qu'elle n'a pas pu lire. Un verdict ne juge que ce qu'on lui a demandé. Un dispositif qui peut ne rien vérifier le dit.
A4 : Un cas joué n'est pas un cas prouvé¶
Un test peut passer sur un écran qui n'a rien affiché. Ce qui se voit se contrôle sur ce que le produit rend, pas sur ce que le test a reconstruit : une capture passe par le code de production, un banc qui maximise tout ne montre pas ce qu'on livre, et la recette a trois états, pas deux.
A5 : La mesure fait foi, et dit d'où elle vient¶
Un relevé qui n'a pas ouvert les fichiers est une hypothèse. Un nombre se lit contre un référentiel cité, un chiffre que le code sait recalculer ne s'écrit pas à la main, et un chiffre qu'il ignore ne s'écrit pas du tout. Un inventaire ne se duplique pas, il se cite. La mesure fait foi en CI, pas sur le poste.
A6 : La vérification se déclare, sur trois niveaux¶
certaine nomme un test ou un script déterministe. probable nomme un script de suspects et son
cliquet. humaine nomme le motif de sa non-mécanisation. Un niveau certaine sans référence
nommée est refusé. Une capacité sait comment on la vérifie à la main ; une affirmation de sécurité
se lit, ou elle n'existe pas.
A7 : Le test précède le code¶
Rouge, vert, refactor, autant de fois qu'il le faut. Sur un défaut, le premier test reproduit le défaut avant qu'une ligne ne soit corrigée.
A8 : La mutation mesure dès qu'un comportement est complet¶
Pas à la clôture. On cible des classes pures, on lance avec une phase, et on lit les survivants un par un. Le pourcentage ne dit rien.
Titre II : la dette¶
A9 : La dette se tient par un cliquet, pas par un nettoyage¶
Une zone au plancher se garde par un refus. Une dette qu'on résorbe par tranches se tient par un cliquet qui ne remonte jamais. Un zéro non gardé ne reste pas zéro, et un cliquet s'apprend en l'appliquant.
A10 : Jamais de suppression d'avertissement¶
Ni @SuppressWarnings, ni //NOPMD. Un avertissement se traite en refactorant.
A11 : L'assumé se déclare, il ne se contourne pas¶
Une règle absente et assumée vaut mieux qu'une règle contournée. Une perte consentie s'annonce, un secret laissé en clair se dit, une exclusion nomme son repreneur ou c'est un trou. Ce qui est assumé et écrit reste discutable ; ce qui est contourné en silence ne l'est plus.
Titre III : rendre compte¶
A12 : Rendre compte avant de conclure, et aucun échec silencieux¶
Un dispositif rapporte ce qu'il a vu avant de conclure. La sévérité se décide à l'émission. Un audit rend tout écart visible, mais un état normal ne crie pas, et un geste qui n'aboutit pas le dit.
A13 : Un refus dit ce qui manque, et ne conseille que le vérifié¶
Le refus nomme ce qui manque, la surface dit quoi faire. Un refus ne conseille que ce qu'il a vérifié applicable, et un refus définitif se réarme sur ce qui a levé sa cause, sur rien d'autre. Un audit qui ne peut pas trancher montre sans juger.
A14 : Un état n'est pas un compte rendu, et ils ne partagent pas de canal¶
Une barre de statut dit où l'on en est, pas si c'est bien ou mal. Rendre compte se fait au bandeau ; le modal est réservé à l'irréversible. Un message montré à l'utilisateur se compose en un seul endroit, et ce n'est pas une vue.
Titre IV : l'état et la donnée¶
A15 : Un état est observé, une décision se prend, ni l'un ni l'autre ne se déduit¶
« Archivé » est un état observé, pas un statut. L'origine d'une donnée est un état porté, pas déduit. Une décision d'affichage se prend, la forme d'un dépôt se choisit, un défaut de plateforme se sonde. Une dérivation automatique ne défait jamais une saisie manuelle.
A16 : L'information se porte dans le type, pas dans la prudence des phrases¶
Un retour d'API est un type scellé. Un invariant tenu par la base se double d'un refus dans le code. Une clé de critère est un contrat de sérialisation : un concept, un endroit, un renommage sans migration.
A17 : Ne rien inventer, ne rien effacer, n'écrire que ce qui est déclaré¶
Écrire sur la plateforme : ne rien inventer, ne rien effacer. On n'écrit jamais plus que ce qui est déclaré. Un traitement en lot compose des gestes unitaires, il n'en invente pas un nouveau. Une restauration vérifie en place, un effacement dit son contrat dans son nom, un script publié ne se modifie plus.
Titre V : le produit¶
A18 : L'utilisateur possède ses fichiers, l'application observe¶
L'application observe la disponibilité des fichiers, elle ne les archive pas. La seule configuration qui vive hors de la base est celle qui dit où la base se trouve.
A19 : Toute capacité métier est offerte aussi en ligne de commande¶
Parité CLI et IHM. La parité d'une sortie machine est de dire, pas de retirer. Un groupe de commandes techniques est borné, et ne dispense pas des commandes métier.
A20 : Le produit ne dépend pas de son outillage¶
Ce que le produit embarque lui appartient : une classe CSS a une seule feuille pour maison, les constantes d'identité d'un installeur sont des constantes, et un outil compose son injecteur depuis la racine.
A21 : La nuit, du crépuscule à l'aube, est l'unité de traitement¶
La nuit se lit du crépuscule à l'aube, pas de minuit à minuit, et elle porte le fuseau de son site, pas celui du poste. Une nuit hors protocole se filtre au lieu de se fondre dans le lot.
A22 : Une feature est un plugin désactivable, et rien ne cycle entre elles¶
Les ponts entre features passent par un port dans commun. Les dialogues bloquants sont des ports
injectables. Un cycle de vie qu'on peut oublier est mal placé.
Titre VI : ce qui se montre¶
A23 : Ce qui s'affiche est embarqué et montré en entier, et rien ne s'offre qui ne se montre¶
La typographie est embarquée, pas empruntée à la machine, et ce que l'application affiche tient dans la police embarquée. Une barre d'actions plie, elle ne tronque pas ; un fil d'Ariane élide des segments, il ne rogne pas des libellés. Un écran n'offre pas un lieu qu'il ne montre pas.
Titre VII : le dépôt¶
A24 : La langue du dépôt est le français¶
Commits, issues, PR, documentation et commentaires. Les mots-clés de fermeture GitHub et les titres structurels des outils restent en anglais, faute de quoi ils cessent de fonctionner. Le sujet d'un commit est une syntaxe, pas une phrase française.
A25 : Le travail de branche est isolé¶
Le dépôt d'origine ne sert qu'à récupérer et tester main. Plusieurs sessions travaillent en
parallèle sous un compte partagé. Un check requis ne gouverne pas les PR, il gouverne la branche, et
le code tiers ne s'exécute pas avec les droits de publication.
A26 : La provenance se déclare¶
Chaque décision porte qui l'a produite et qui l'a relue. L'assistance par agents est déclarée, pas déduite. L'identité de distribution est distincte de celle de l'auteur et de celle de la plateforme.
A28 : Un avertissement se dit en mots¶
Un pictogramme d'alerte n'apporte pas l'information : il annonce qu'il y en a une. Posé sur plus de mille lignes et des centaines de fichiers, il ne distingue plus rien. Ce qui doit alerter se dit dans la phrase, ou dans l'encart que le format prévoit. Le pictogramme ne subsiste que là où il est le contenu montré : une maquette qui rend ce que l'écran affiche, un message que le programme émet.
A29 : L'ergonomie se rattache à une heuristique nommée¶
Une décision qui porte sur l'usage - ce qu'un écran montre, ce qu'il refuse, ce qu'il fait attendre -
déclare par le champ heuristiques: de son en-tête la ou les heuristiques qu'elle sert. Le
vocabulaire est clos : dix heuristiques de Nielsen, l'affordance et le signifiant de Norman, six
lois de la Gestalt, tenues par dev-docs/ergonomie/heuristiques.md. Une clé hors vocabulaire est
refusée. Une décision rattachée à A12, A13, A14, A15, A18, A19, A23 ou A28 qui ne déclare rien est un
suspect sous cliquet, pas un refus : le rattachement se fait par tranches, chaque décision ouverte
et lue, jamais par ressemblance de mots. Une heuristique que rien ne sert est dite dans le rapport,
sans faire rougir : c'est un manque à connaître, pas une faute à corriger.
A30 : Le code dit ce qu'il fait, la javadoc dit son contrat, l'ADR dit pourquoi¶
Trois endroits, un rôle chacun. Le code porte l'intention : un nom qui la dit, une fonction qui tient dans un écran, un type qui rend l'erreur impossible. Un commentaire qui explique un nom est un nom à changer ; un commentaire qui paraphrase la ligne suivante s'enlève. La javadoc dit le contrat - ce qu'on fournit, ce qu'on obtient, ce qui peut être nul - et s'adresse à qui appelle. L'ADR dit pourquoi, et la javadoc la cite au lieu de la redire.
Ce qui est caduc s'enlève : git log garde l'histoire pour qui la cherche, et une javadoc dont une
moitié est périmée ne se lit plus du tout. Un bloc de plus de huit lignes de prose est un suspect
sous cliquet, dans le code de production ; un garde, lui, doit dire ce qu'il vérifie.
A31 : La prose visible se relit à l'humaniseur¶
Toute prose qu'un humain lira hors de l'échange qui l'a produite - javadoc, documentation, ADR,
libellés d'interface et de ligne de commande, messages de commit, corps d'issue et de pull request -
passe la grille de la compétence humaniser avant d'être publiée, par un commit comme sur la
forge. Les sept tics de CONTRIBUTING.md en sont le sous-ensemble
opposable : la grille sert à relire, les sept servent à refuser. Rien ne mécanise le reste, et c'est
dit : aucun motif textuel ne décide si une emphase informe, ni si une javadoc paraphrase la
signature qu'elle surmonte.
Matrice de traçabilité¶
Engendrée depuis les en-têtes des ADR par scripts/methode/matrice-constitution.py, et gardée par lui.
| Article | Jurisprudence | Dont mécanisée | Tenu par |
|---|---|---|---|
| A1 · La preuve précède l'affirmation | 6 | 1 | .github/scripts/verifie_decisions_du_tournage_connecte.py, .github/scripts/verifie_jeton_vivant.py, .github/scripts/revoque_jeton.py, et 1 autre |
| A2 · Un garde est vu rouge sur sa propre mutation | 15 | 10 | src/test/bats/cli.bats, src/test/java/fr/univ_amu/iut/architecture/AnnonceDesMutationsTest.java, .github/scripts/mesure_duree_portail.py, et 7 autres |
| A3 · Un dispositif dit ce qu'il couvre, et ce qu'il n'a pas pu lire | 35 | 27 | .github/scripts/veille_contrat_api.py, AnalyseViewTest#colonne_commune_sur_la_table_des_observations, SiteEditRechercheCarreTest#un_verdict_arrive_en_retard_est_ecarte, et 28 autres |
| A4 · Un cas joué n'est pas un cas prouvé | 26 | 15 | ApercuFxElisionTest#bouton_tronque_refuse, ActiviteViewTest#l_export_image_redessine_un_graphe_reellement_dessine, scripts/adr/3053-capture-libelle.py, et 13 autres |
| A5 · La mesure fait foi, et dit d'où elle vient | 31 | 17 | GenerationCartesSDCliquetTest#chaque_spec_produit_la_pathologie_attendue, ReferentielActiviteTest#precise_mais_peu_fiable_ecartee, EspecesPrioritairesReferentielTest#marque_toutes_les_prioritaires_connues, et 13 autres |
| A6 · La vérification se déclare, sur trois niveaux | 3 | 2 | DocumentationAJourTest#la_verification_declaree_par_une_adr_existe_vraiment, EcritureAtomiqueTest#creation_restreinte |
| A7 · Le test précède le code | 1 | 1 | BancDesClipsTest#une_classe_filmee_neuve_declare_son_banc |
| A8 · La mutation mesure dès qu'un comportement est complet | 0 | 0 | relecture seule |
| A9 · La dette se tient par un cliquet, pas par un nettoyage | 21 | 11 | scripts/adr/2843-tiret-cadratin.py, PatronDuCliquetTest#tout_cliquet_passe_par_le_patron, scripts/adr/verifie_scripts.py, et 18 autres |
| A10 · Jamais de suppression d'avertissement | 0 | 0 | relecture seule |
| A11 · L'assumé se déclare, il ne se contourne pas | 13 | 0 | scripts/adr/verifie_verdicts_declares.py |
| A12 · Rendre compte avant de conclure, et aucun échec silencieux | 11 | 7 | scripts/adr/0008-echec-silencieux.py, .github/scripts/verifie_secret_winget.py, RetourOperationTest#les_deux_causes_ne_se_melangent_pas, et 9 autres |
| A13 · Un refus dit ce qui manque, et ne conseille que le vérifié | 9 | 8 | scripts/adr/2635-refus-sans-surface.py, AuditDepartementDuPointTest#legitime_et_suspecte_indiscernables, FiltresLieuTest#le_point_est_filtrable, et 6 autres |
| A14 · Un état n'est pas un compte rendu, et ils ne partagent pas de canal | 8 | 2 | CompteRenduChiffreTest#ventilation_non_exhaustive_refusee, CauseLisibleTest#l_enveloppe_de_reflexion_ne_masque_pas_la_panne, scripts/adr/3947-message-enveloppe.py |
| A15 · Un état est observé, une décision se prend, ni l'un ni l'autre ne se déduit | 21 | 16 | DecisionsRespecteesTest#archive_n_est_pas_un_statut_de_workflow, RapprochementNuitsOpportunistesTest#ne_demarque_jamais_une_saisie_manuelle, PolitiqueReessaiTest#refus_definitif_ne_reessaie_pas, et 13 autres |
| A16 · L'information se porte dans le type, pas dans la prudence des phrases | 13 | 11 | DecisionsRespecteesTest#l_echelle_de_severite_a_quatre_niveaux_dans_l_ordre, ClesCriteresTest#aucune_cle_publiee_deux_fois, CritereLieuTest#un_carre_une_entree_deux_etiquettes, et 8 autres |
| A17 · Ne rien inventer, ne rien effacer, n'écrire que ce qui est déclaré | 31 | 20 | MoteurTraitementGroupeTest#annulation_apres_le_passage_courant, RestaurationCompleteTest#restauration_sur_une_autre_machine, EmpreinteMigrationsTest#script_modifie_apres_coup_fait_refuser, et 32 autres |
| A18 · L'utilisateur possède ses fichiers, l'application observe | 4 | 2 | WorkspaceTest#resolu_lit_la_configuration_persistee, ServiceImportReferenceTest#reference_pose_identite_et_placeholder |
| A19 · Toute capacité métier est offerte aussi en ligne de commande | 5 | 4 | ArchitectureTest#lecture_brute_reservee_au_groupe_api, ExportSyntheseCsvTest#referentiel_indisponible_conserve_les_colonnes, FiltresActiviteTest#ce_qui_qualifie_rend_vide_sans_refuser, et 1 autre |
| A20 · Le produit ne dépend pas de son outillage | 6 | 6 | DecisionsRespecteesTest#l_installeur_windows_porte_ses_constantes_d_identite, DoublonsFeuillesDeStyleTest#chaque_classe_a_une_seule_feuille, ArchitectureTest#produit_sans_outillage, et 3 autres |
| A21 · La nuit, du crépuscule à l'aube, est l'unité de traitement | 6 | 3 | AgregationActiviteTest#l_export_date_ses_lignes_par_la_nuit_biologique, NatureNuitTest#un_passage_marque_est_une_participation_opportuniste, CorrespondanceParticipationTest#le_depot_ne_depend_pas_du_poste |
| A22 · Une feature est un plugin désactivable, et rien ne cycle entre elles | 4 | 2 | DecisionsRespecteesTest#aucun_cycle_entre_les_features, scripts/adr/0010-dialogue-hors-port.py, NavigateurTest#relibeller_ne_reabonne_pas |
| A23 · Ce qui s'affiche est embarqué et montré en entier, et rien ne s'offre qui ne se montre | 17 | 11 | scripts/adr/0035-pictogramme-caractere.py, scripts/adr/0037-slot-actions-hbox.py, scripts/adr/2493-modale-suit-croissance.py, et 12 autres |
| A24 · La langue du dépôt est le français | 2 | 2 | .github/scripts/verifie_titre_pr.py, scripts/methode/verifie-controle-du-titre.py |
| A25 · Le travail de branche est isolé | 3 | 1 | .github/scripts/verifie_epinglage.py |
| A26 · La provenance se déclare | 4 | 2 | DecisionsRespecteesTest#l_installeur_porte_l_identite_echonuit, DocumentationAJourTest#une_adr_recente_porte_le_numero_de_son_chantier |
| A28 · Un avertissement se dit en mots | 1 | 0 | scripts/adr/4366-avertissement-en-pictogramme.py |
| A29 · L'ergonomie se rattache à une heuristique nommée | 1 | 0 | scripts/adr/verifie_okf.py |
| A30 · Le code dit ce qu'il fait, la javadoc dit son contrat, l'ADR dit pourquoi | 6 | 2 | scripts/adr/4359-javadoc-narratif.py, scripts/adr/4359-blocs-relus.py, scripts/adr/4395-renvois-en-javadoc.py, et 3 autres |
| A31 · La prose visible se relit à l'humaniseur | 4 | 1 | .github/scripts/verifie_corps_pr.py, scripts/adr/4783-traces-d-outil.py |
2 article(s) sur 30 ne sont tenus que par la relecture. C'est la liste des chantiers de garde restants, et elle se lit comme un inventaire, pas comme une fatalité.
- A8 · La mutation mesure dès qu'un comportement est complet
- A10 · Jamais de suppression d'avertissement