Files
decision/docs/adr/0009-modules-ordre-et-titre.md
T
YvvandClaude Opus 5.5 033b331228 Fusion de la tête du chantier (924a40d : lots B2 et F) dans le lot D
Les deux côtés gardés partout. Aux coutures :
- une objection (redit / contredit) porte sur deux articles, jamais sur un module ;
  un ordre ne se corrige pas, ni par son auteur ni par un autre ; une coquille du
  titre suit le chemin de F (l'auteur du titre, un administrateur pour le titre
  de départ, ou 3 jours), et documents.title suit à l'application ;
- votable() couvre les modules ; leurs totaux passent par shown_tally, à l'écran
  et dans document.json ;
- « Modules à voter » ne compte plus une version retenue par une objection (test
  vu rouge) ; la liste du groupe la compte toujours parmi les propositions en cours ;
- le panier : une fonction pour les articles et les modules, avec les versions
  retenues de F ; un nouvel article se propose dans une section, à sa fin, et peut
  répondre à une objection ;
- migrations 0007 (modules) puis 0008 (objections) ;
- C25 et C26 supportent un groupe d'essai où une voix suffit (dès 16 membres).

Boucle : fmt, clippy -D warnings, cargo test (227), svelte-check 0, vitest 55,
build, e2e 35 / 35 (C1–C33 et M1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:41:30 +01:00

8.5 KiB
Raw Blame History

0009 — Les modules : l'ordre des articles de chaque section, le titre du document

Complète 0002 (vote permanent), 0007 (inertie à cinq crans) et 0008 (vote par la chaîne). Décisions d'Yvv à la revue du 2026-10-30 (L11) ; la règle des articles qui entrent ou sortent pendant le vote d'un ordre est le choix du lot D, isolé dans ld-engine pour être changé seul.

Contexte. Un texte de référence vit article par article : chacun entre en vigueur à son seuil. Deux choses n'avaient pas de vote : la place des articles dans leur section (fixée par le seed, puis « après tel article » au choix de qui proposait) et le titre du document (écrit une fois, au seed). Yvv, 2026-10-30 : « En fin de section, il y a un "module" qui permet de changer l'ordre des "articles". Lui-même à (2), avec une simple liste clipable. » ; « Le titre du doc à (4). » ; « Non, titre et texte ensemble » — le titre d'un article reste voté avec son texte : seul le titre du document est un module à part.

Décision

Un module est une unité du document, ses versions sont des propositions

units.kind (article par défaut, title, order ; migration 0007_modules.sql, additive). Un module a, comme un article, une inertie, une version en vigueur, des propositions ouvertes, des votes, des changements d'inertie. Tout ce qui sert au vote d'un article lui sert sans chemin à part : le vote déplié, le panier, le bulletin sur la chaîne Ğ1 (ballots.rs valide les lignes contre les propositions du document : un module y est), le balayage, l'adoption (ld_engine::compose), la marge du texte en place (0002), le cran (0007), « Décisions » (ld_engine::pending).

  • Le titre du document — code titre, inertie 4. Une version = un titre dans la langue source (corps vide). Elle se propose en tête du lecteur (« Proposer un autre titre », POST /api/units/{id}/title) ; une coquille s'y corrige sans vote (0003) ; elle se traduit.
  • L'ordre d'une section — code ordre.<section>, inertie 2, un par section. Une version = la liste des articles de la section, un identifiant par ligne. Elle se propose en fin de section (« Proposer un autre ordre », POST /api/units/{id}/order) avec une liste où l'on clique : un article, puis sa nouvelle place, ou ses flèches, ou le clavier (Entrée choisit, haut et bas déplacent). Un ordre ne se corrige pas et ne se traduit pas (409 order_fixed) : on en propose un autre.
  • L'écriture générique (POST /api/docs/{id}/proposals) refuse un module (400 module) : chacun se propose à sa place.

Qui est dans l'ordre d'une section

Les articles de la section qui ont un texte en vigueur ou une version ouverte (texte ou retrait) ; ni les brouillons, ni les retirés. Dans l'ordre des positions. La même règle en Rust (DocState::members) et en SQL (order::sections_now). Une section d'un seul article n'a rien à décider : son ordre n'est jamais « à voter », ni montré, ni compté (Module.moot).

Quand des articles entrent ou sortent pendant le vote d'un ordre : complété à la fin

Une proposition d'ordre garde les votes reçus. Ce qui est voté est l'ordre relatif des articles qu'elle nomme ; on le lit toujours contre les articles présents (ld_engine::order::fit) :

  • les articles encore dans la section gardent l'ordre proposé ;
  • un article arrivé depuis se place à la fin, dans l'ordre de la section (« 1 article entré depuis, placé à la fin ») ;
  • un article sorti (retiré, rejeté) disparaît de l'ordre, sans autre effet ;
  • une proposition qui, ainsi complétée, redit l'ordre en vigueur ne peut pas entrer (« c'est l'ordre en vigueur ») : elle reste ouverte, sans effet, jusqu'à ce qu'un autre ordre entre.

Écartées : caduque (un vote permanent dans une section vivante ne passerait jamais : chaque nouvel article remettrait les compteurs à zéro) et à reconfirmer (même effet, plus lent, et demande aux votants un geste qu'ils ne savent pas devoir faire). Compléter à la fin respecte ce qui a été voté — l'ordre entre les articles connus — et la règle de placement par défaut.

Les articles nouveaux se placent à la fin de leur section

Une proposition de nouvel article nomme sa section ; elle s'y place à la fin (ld_engine::order::place_at_end). Un ancien client qui nomme un article (afterUnitId) obtient la fin de la section de cet article. « Après tel article » n'existe plus : la place se vote, par l'ordre de la section.

Quand un ordre entre en vigueur

Il redistribue les positions déjà tenues par la section à ses articles, dans le nouvel ordre (ld_engine::order::positions) : rien ne bouge hors de la section, aucun texte ne change, aucun vote d'article n'est touché. L'ordre d'avant redevient une proposition ouverte, avec ses votes, et peut revenir.

Quand un titre entre en vigueur

documents.title prend le nouveau titre dans la langue source. Les traductions restent éditoriales (le français voté fait foi) : la nouvelle version reprend celles du titre qu'elle remplace, attachées au texte de ce titre-là, donc « traduction à revoir » jusqu'à ce qu'une personne traduise le nouveau. Le titre du document dans les autres langues suit ses traductions, fraîches ou à revoir (doc_title::sync, rejoué aussi à chaque mise en file de publication : une coquille ou une traduction du titre en vigueur s'y reporte).

Face aux objections et aux coquilles des autres (ADR 0010)

  • Une objection (« redit », « contredit ») porte sur deux versions d'articles, jamais sur un module : un titre ou un ordre ne se répète ni ne se contredit au sens d'un article (objections::raise n'admet que des textes ; test the_generic_writing_stops_at_a_module_and_an_order_is_never_corrected).
  • Un ordre ne se corrige pas (409 order_fixed), ni par son auteur ni par un autre : pas de coquille d'un autre sur un ordre. Une coquille du titre suit le chemin de toute coquille : celle d'un autre attend l'auteur du titre (un administrateur pour le titre de départ) ou 3 jours ; appliquée, elle republie, et documents.title suit.
  • DocState::votable couvre les modules comme les articles ; les totaux d'un module se lisent par shown_tally, à l'écran et dans document.json.
  • « Modules à voter » ne compte pas une version retenue par une objection : personne ne peut la voter tant qu'elle est retenue (un article dont la seule version ouverte est retenue sort du compte, et y revient à la levée). La liste du groupe la compte toujours parmi les propositions en cours, ouvertes.

Publication

fr.md ne change pas de forme : les articles dans leur ordre en vigueur, sous le titre en vigueur. en.md / es.md portent une ligne de commentaire quand la traduction du titre est à revoir. document.json gagne modules : le titre (inertie, statut, date d'entrée, votes, traductions et leur fraîcheur) et chaque ordre (section, inertie, statut, date, votes, articles par leur code).

Les documents qui existent déjà

Le seed déclare les crans ("modules": {"title": {"inertia": 4}, "order": {"inertia": 2}}) ; une base neuve crée les modules en même temps que les articles. Un document existant les reçoit par un ajout gardé (crates/ld-server/src/module_amend.rs, dans la ligne de seed_amend.rs et inertia_amend.rs) : une seule fois par document (journal module_amendments, migration 0007), depuis l'état présent — le titre en vigueur est le titre actuel du document, avec ses traductions ; l'ordre en vigueur d'une section est l'ordre actuel de ses articles —, sans toucher un article ni un vote. Les versions créées sont des « seed a minima » (en vigueur sans vote, marge −C) : elles restent sous vote comme tout texte. Un document qui a déjà des modules, ou sans titre, est noté et laissé.

Ce que ça coûte

  • Le seed de l'acte d'engagement passe de 33 à 41 modules à voter : 33 articles, le titre, et l'ordre de 7 sections (l'ordonnancement n'a qu'un article). C17 et les comptes de « Décisions » le disent.
  • Les aperçus (« si les bien cotées passent », « si tout passe ») montrent les articles seuls : un ordre ou un titre proposé n'y change pas encore la place des articles ni le titre.
  • Un ordre ouvert sur une section revenue à un seul article reste en base, sans être montré ni compté.
  • Les codes des nouveaux articles restent N<n> (sans lien avec la section), comme avant.