Dépouillement & recompte
Le résultat n'est jamais un bloc du registre : c'est un recalcul déterministe, à partir de la configuration publiée et des bulletins signés, que chacun peut rejouer.
Ce qui fait foi, c'est la liste figée des bulletins signés ; le recalcul en est une contre-vérification. Une divergence entre deux implémentations ou deux versions de bibliothèque serait un défaut d'un programme de calcul, pas une faille de vérifiabilité : les bulletins publiés restent inchangés. Toutes les méthodes proposées sont déterministes, le résultat est donc stable pour une liste de bulletins donnée.
Protocole v1
Ce que lit le recompte.
Uniquement des données publiques : la configuration gelée (bloc 0), les bulletins (blocs de votes), la liste d'émargement de clôture pour les poids, et la méthode publiée avec le résultat. Le document CEF n'est pas une entrée nécessaire.
-
candidates[].labelchaînes · configuration - Les candidats déclarés, y compris ceux que personne n'a classés. L'étiquette est le seul identifiant de candidat.
-
election_typepreferential | fptp · configuration - Classement (méthodes de Condorcet) ou choix unique (scrutin majoritaire). Fixe aussi la règle de classement implicite.
-
ballot_rulesobjet · configuration - Les quatre paramètres de bulletin, dont les contraintes de dépouillement se déduisent par une règle fixe (ci-dessous).
-
seatsentier ≥ 1 · configuration - Le nombre d'élus : les seats premières places du classement.
-
weighted_votingbooléen · configuration - Si vrai, chaque bulletin pèse le poids signé dans sa charge utile ; sinon, chaque bulletin pèse 1.
-
ballots[].payloadchaîne JSON · votes - La charge utile signée : son champ ballot (classement CEF ou /EMPTY_RANKING/) et son champ weight.
-
electoral_roll[].weightentier ≥ 1 · closure - Le poids autorisé de chaque votant, pour contrôler les poids signés d'une élection pondérée.
-
méthodenom canonique · résultat - Choisie par l'organisateur, gelée avec la configuration au lancement, publiée avec le résultat et non dans la chaîne. Désignée par son nom exact dans la bibliothèque, par exemple Schulze Winning.
Chaque bulletin publié, une règle mécanique.
Le contenu d'un bulletin n'est pas validé au dépôt : le dépouillement tranche, selon une règle publique et déterministe. Un bulletin écarté reste publié et vérifiable ; il est seulement exclu du classement.
- 1 Vérifier. Chaque bulletin publié porte une signature en anneau valide et une image de clé unique dans l'élection : la plateforme le contrôle à la réception, le vérificateur le recontrôle. Un échec serait une faute du registre, pas une règle de dépouillement.
- 2 Filtrer le format. Le champ ballot passe le contrôle strict de cef-writer : chaîne vide, séparateur de tag ||, rang vide (A>>B), UTF-8 invalide, saut de ligne, caractères réservés ; , # / * ^ ou candidat répété le rejettent. L'analyseur de la bibliothèque le lit ensuite, et peut le refuser à son tour. Un bulletin rejeté est nul par format : il ne devient jamais un vote.
- 3 Reconnaître le blanc. La sentinelle /EMPTY_RANKING/ est un bulletin blanc : une abstention, comptée.
- 4 Appliquer les contraintes. Les contraintes déduites de ballot_rules classent chaque vote valide ou nul par contrainte. Un classement qui nomme un candidat non déclaré compte comme exprimé ; le nom inconnu est ignoré dans les duels.
- 5 Peser. Dans une élection pondérée, le poids appliqué est le weight de la charge utile signée, jamais un multiplicateur lu dans le classement (le filtre de format l'interdit). Les poids signés doivent former exactement le multiensemble des poids des votants marqués has_voted, dont la somme vaut totals.voted_weight. Sans pondération, chaque vote pèse 1.
Des paramètres aux contraintes
-
NoTiesi ties_allowed = false - Rejette un vote qui exprime une égalité, y compris l'égalité implicite des candidats non classés d'un classement partiel.
-
NoBlankVotesi blank_allowed = false - Rejette le bulletin blanc : il est alors nul par contrainte au lieu de blanc.
-
CompleteRankingsi partial_ranking_allowed = false - Rejette un classement qui ne nomme pas explicitement tous les candidats.
-
Implicit Rankingselon election_type - Activé pour preferential : un candidat non classé est à égalité en dernière position. Désactivé pour fptp : un choix unique laisse les autres candidats non classés.
Les contraintes ne sont pas publiées en tant que telles : elles se déduisent des paramètres publiés par cette règle. Un blanc est une abstention, ni une égalité ni un classement partiel : NoTie et CompleteRanking l'exemptent, seul NoBlankVote le rejette. La plateforme applique cette exemption par ses propres variantes des contraintes natives de CondorcetPHP ; un recompte indépendant doit la reproduire.
Pour une élection fptp, les paramètres publiés sont fixes (égalités interdites, classement partiel permis, classement complet jamais exigé) : NoTie s'applique toujours, NoBlankVote si l'abstention est interdite. Un classement à plusieurs préférences y est lu à sa première préférence.
Six compteurs, deux invariants.
Calculés une fois par dépouillement, identiques pour toutes les méthodes. Un recompte sous les mêmes contraintes doit les reproduire exactement.
-
totalentier - Les votes enregistrés par la bibliothèque.
-
validentier - Les votes qui passent toutes les contraintes.
-
expressedentier - Les votes valides et non blancs : ceux qui font le classement.
-
blankentier - Les votes valides au classement vide (/EMPTY_RANKING/).
-
invalidByConstraintentier - Les votes enregistrés mais rejetés par une contrainte : les nuls par contrainte.
-
invalidByFormatentier - Les bulletins qui ne sont jamais devenus un vote : les nuls par format, hors de total.
total = valid + invalidByConstraint ; valid = expressed + blank. Le nombre de nuls publié est invalidByFormat + invalidByConstraint. Le même découpage, sommé par poids plutôt que par bulletin, donne les voix d'une élection pondérée (sans pendant pour invalidByFormat : ces bulletins ne portent aucun poids) ; sans pondération, il recopie les comptes.
Une méthode, fixée avant le vote.
La plateforme n'implémente aucun algorithme de vote : chaque méthode est celle de la bibliothèque julien-boudry/condorcet (CondorcetPHP), désignée par son nom exact. Le type d'élection est publié dans le bloc 0 ; la méthode, choisie par l'organisateur, est gelée avec la configuration au lancement et publiée avec le résultat.
-
FPTPfptp - Scrutin majoritaire uninominal : le candidat qui recueille le plus de voix l'emporte, de poids en élection pondérée. Le résultat reste un classement complet.
-
Schulze Winningpreferential · par défaut - Schulze, variante des votes gagnants.
-
Schulze Marginpreferential - Schulze, variante des marges.
-
Ranked Pairs Winningpreferential - Ranked Pairs (Tideman), variante des votes gagnants.
-
Ranked Pairs Marginpreferential - Ranked Pairs (Tideman), variante des marges.
-
Copelandpreferential - Méthode de Copeland.
-
Dodgson Quickpreferential - L'approximation polynomiale de la méthode de Dodgson.
- Une variante, un nom. Chaque variante est un choix distinct, associé un pour un au nom canonique de la bibliothèque : la méthode enregistrée se rejoue telle quelle.
- Déterministes seulement. Aucune méthode non déterministe n'est proposée : les mêmes bulletins donnent toujours le même résultat.
- La pondération n'est pas une méthode. Avec weighted_voting, la même méthode s'applique, chaque vote portant son poids, que la bibliothèque compte nativement.
- Les sièges sont une coupe. Les élus sont les seats premières places du classement rendu ; rien d'autre n'est calculé. Les méthodes proportionnelles de la bibliothèque ne sont pas proposées.
- Méthodes secondaires, à titre indicatif. Pour une élection Condorcet, la page de résultats peut montrer le classement qu'auraient donné les autres méthodes de la liste sur les mêmes bulletins. Seule la méthode principale fait le résultat officiel.
Aucun départage inventé.
La plateforme rapporte ce que rend la bibliothèque et ne retouche jamais le vainqueur.
- Rangs partagés. Le classement est numéroté à partir de 1 ; des candidats à égalité partagent le même rang.
- Cycles. En l'absence de vainqueur de Condorcet, le cycle est résolu par la méthode configurée, et par elle seule.
- Égalité à la coupe des sièges. Si une égalité chevauche la frontière entre la N-ième et la (N+1)-ième place, personne n'est déclaré élu au-delà de la frontière. L'organisateur tranche hors de la plateforme, typiquement par un second tour organisé comme une nouvelle élection.
- Aucun bulletin. Sans bulletin, il n'y a rien à dépouiller : le résultat officiel est vide (comptes à zéro, classement vide, aucun élu), sans appel à la bibliothèque.
La version du calcul, enregistrée avec le résultat.
Chaque résultat enregistre de quoi rejouer exactement la même sémantique : la version du contrat de dépouillement, la version de la bibliothèque et la méthode. La page de résultats publique affiche la méthode et, pour une élection Condorcet, la version de la bibliothèque.
-
engine_contract_versionentier · aujourd'hui 1 - La version du contrat de dépouillement (affichable « v1 ») : la forme du document de résultat et les règles de comptage décrites sur cette page.
-
condorcet_library_versionchaîne - La version de julien-boudry/condorcet qui a calculé le résultat (Condorcet::VERSION).
-
methodchaîne - Le nom canonique de la méthode, tel que la bibliothèque le rapporte (Result->fromMethod).
-
counts, weightsobjets - Les six compteurs ci-dessus et leur pendant pondéré.
Le document de résultat est conservé tel que la bibliothèque le produit : pour chaque méthode, le classement, le vainqueur et le perdant, le vainqueur et le perdant de Condorcet, les avertissements ; en option, la matrice des duels. La seule opération ajoutée par la plateforme est la coupe des seats premières places.
Une commodité, pas une pièce du protocole.
Une fois le dépouillement terminé et le résultat publié, la page de résultats propose les bulletins au Condorcet Election Format (CEF), un format texte ouvert dont la spécification est publique, lisible par la bibliothèque Condorcet comme par toute implémentation conforme.
- Jamais nécessaire. Le document se reconstruit à partir du seul registre : un vérificateur peut le régénérer pour recouper le fichier servi, et le recompte n'en a pas besoin.
- Sans contraintes ni méthode. Elles n'y figurent pas : elles se lisent dans ballot_rules et dans le résultat publiés.
- Régénéré à chaque dépouillement. Produit après chaque dépouillement réussi, y compris pour une élection sans bulletin ; un nouveau dépouillement produit un nouveau document. Il n'est jamais purgé.
- /elections/{election}/results/ballots.cef
- Redirige vers le document stocké, une fois l'élection publiée et le dépouillement terminé.
Contenu du document
-
#/Candidates:paramètre - Les étiquettes officielles, déclarées d'emblée : un candidat que personne n'a classé existe quand même.
-
#/Implicit Ranking:paramètre - true pour une élection preferential, false pour une élection fptp.
-
#/Weight Allowed:paramètre, pondération seulement - Présent seulement dans une élection pondérée ; chaque ligne de vote porte alors son poids signé.
-
une ligne par bulletinclassement CEF - Le champ ballot de chaque charge utile publiée, écrit par cef-writer, blancs /EMPTY_RANKING/ compris. Les nuls par format n'y figurent pas.
Rejouer le dépouillement soi-même.
Avec la bibliothèque de référence à la version enregistrée, le recompte reproduit le classement et les comptes à l'identique. Toute autre implémentation conforme au CEF devrait, en théorie, aboutir au même résultat.
- 1 Télécharger le registre de l'élection et vérifier chaque bulletin : signature, unicité des images de clé, cohérence avec la liste d'émargement et, en élection pondérée, avec les poids.
- 2 Lire dans le bloc 0 les candidats, le type, ballot_rules, seats et weighted_voting ; en déduire les contraintes et la règle de classement implicite.
- 3 Écrire chaque charge utile publiée en CEF avec cef-writer, ou appliquer le même filtre de format, avec son poids signé si l'élection est pondérée ; les rejets sont les nuls par format.
- 4 Calculer avec julien-boudry/condorcet, à la version enregistrée, la méthode publiée avec le résultat, sous les contraintes déduites, le blanc exempté de NoTie et de CompleteRanking.
- 5 Comparer le classement et les six compteurs au résultat publié, puis lire les élus : les seats premières places.
Voir aussi
- Registre public Ce que chaque élection publie, indépendamment de son transport : définition, anneaux, émargement, bulletins.
- Procédure de vérification Vérifier une élection de bout en bout : à partir du registre seul, ou avec la blockchain.
- Bulletin signé Le bulletin tel que le votant le signe : charge utile, signature en anneau, image de clé, condensé d'anneau.