Spaces:
Running
feat(sprint-A10): gouvernance institutionnelle (CODEOWNERS + GOVERNANCE + CoC + COI)
Browse filesSprint A10 — Politiques de gouvernance (2 PJ, items M-10 + M-11).
Items résolus :
- M-11 : ``.github/CODEOWNERS`` — désignation des reviewers par
sous-package. Catch-all ``* @maribakulj`` + ownership renforcé sur
Cercle 1 (core/, api-stable.md), Cercle 2, Cercle 3, configs
projet (pyproject, Dockerfile, workflows). Domain experts
(paléographe, archiviste, référent a11y) déjà préparés en
commentaires pour invitation future.
- M-11 : ``GOVERNANCE.md`` (220 lignes) :
- Rôles : BDFL @maribakulj actuel ; promotion reviewer après
3 PR mergées ; domain experts (paléographie, a11y, NLP) ;
transition steering committee si > 5 mainteneurs.
- Cadence release : patch à la demande, mineure mensuelle,
majeure trimestrielle, hotfix sécu < 72 h.
- SLO : triage issue 5j ouvrés, revue PR 7j, sécu critique 5j,
release patch sécu 3j (best-effort, non contractualisé).
- Politique breaking changes : 2 versions mineures de dépréciation
avant suppression, bump majeur exigé pour incompat API publique.
- Procédure transfert mainteneur (3 mois shadow + bascule droits
GitHub + update CITATION).
- Mode archive si pas de successeur en 6 mois.
- M-11 : ``CODE_OF_CONDUCT.md`` (140 lignes) — adoption du
Contributor Covenant 2.1 verbatim (standard de facto, traduit
30+ langues). 4 niveaux d'application : Correction →
Avertissement → Bannissement temporaire → Bannissement permanent.
Voies de signalement : issue privée, DM mainteneur, défenseur
des droits FR pour cas graves.
- M-10 : section ``Conflicts of interest`` dans GOVERNANCE.md :
- Affiliations des mainteneurs déclarées (aucune chez fournisseur
benchmarké).
- Indépendance des données pricing : tarifs publics uniquement,
pas de NDA, datés explicitement, surchargeable par l'utilisateur.
- Indépendance éditoriale du moteur narratif : seuils symétriques,
aucune logique privilégie un fournisseur.
- Politique sponsoring : transparence si financement futur,
aucune restriction d'usage acceptable.
Tests : ``tests/docs/test_governance_files_present.py`` (20 cas) :
- 7 fichiers de gouvernance présents et non vides
(CODEOWNERS, GOVERNANCE, CoC, SECURITY, ACCESSIBILITY, LICENSE,
CONTRIBUTING).
- CODEOWNERS a une ligne catch-all.
- GOVERNANCE documente cadence release + SLO.
- GOVERNANCE contient section COI mentionnant ≥ 3 fournisseurs
cloud (OpenAI, Anthropic, Mistral, Google, Azure).
- GOVERNANCE traite l'indépendance des données pricing.
- CoC s'appuie sur Contributor Covenant + 4 niveaux d'application.
- GOVERNANCE link les autres docs (CONTRIBUTING, CoC, SECURITY,
ACCESSIBILITY).
Tests : 20/20 verts. Suite complète à valider.
- .github/CODEOWNERS +76 -0
- CODE_OF_CONDUCT.md +149 -0
- GOVERNANCE.md +205 -0
- tests/docs/test_governance_files_present.py +151 -0
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Sprint A10 (M-11) — désignation des mainteneurs de revue par sous-package.
|
| 2 |
+
#
|
| 3 |
+
# Format : ``<chemin> @utilisateur1 @utilisateur2 @org/team-name``
|
| 4 |
+
# GitHub assigne automatiquement les utilisateurs nommés ici comme
|
| 5 |
+
# reviewers requis sur toute PR qui touche les chemins correspondants.
|
| 6 |
+
#
|
| 7 |
+
# Politique :
|
| 8 |
+
# - Tout fichier de l'arbre a au moins un mainteneur désigné (catch-all
|
| 9 |
+
# en première ligne).
|
| 10 |
+
# - Les sous-packages ``core/`` et ``measurements/`` ont une revue
|
| 11 |
+
# renforcée car ils définissent les contrats de l'API publique.
|
| 12 |
+
# - Les guides développeur et la doc institutionnelle ont une revue
|
| 13 |
+
# ciblée sur la cohérence éditoriale (cf. GOVERNANCE.md).
|
| 14 |
+
#
|
| 15 |
+
# À mettre à jour quand un nouveau mainteneur rejoint l'équipe ou
|
| 16 |
+
# qu'un domain expert (paléographe, archiviste, dev a11y) prend en
|
| 17 |
+
# charge un sous-domaine spécifique.
|
| 18 |
+
|
| 19 |
+
# ──────────────────────────────────────────────────────────────────
|
| 20 |
+
# Catch-all : revue par défaut sur toute PR.
|
| 21 |
+
# ──────────────────────────────────────────────────────────────────
|
| 22 |
+
* @maribakulj
|
| 23 |
+
|
| 24 |
+
# ──────────────────────────────────────────────────────────────────
|
| 25 |
+
# Cercle 1 — abstractions pures (API publique stable).
|
| 26 |
+
# Toute modification ici peut casser des consommateurs externes :
|
| 27 |
+
# revue prioritaire, tests anti-régression renforcés.
|
| 28 |
+
# ──────────────────────────────────────────────────────────────────
|
| 29 |
+
/picarones/core/ @maribakulj
|
| 30 |
+
/docs/api-stable.md @maribakulj
|
| 31 |
+
|
| 32 |
+
# ──────────────────────────────────────────────────────────────────
|
| 33 |
+
# Cercle 2 — métriques et orchestration.
|
| 34 |
+
# ──────────────────────────────────────────────────────────────────
|
| 35 |
+
/picarones/measurements/ @maribakulj
|
| 36 |
+
/picarones/engines/ @maribakulj
|
| 37 |
+
/picarones/llm/ @maribakulj
|
| 38 |
+
/picarones/pipelines/ @maribakulj
|
| 39 |
+
/picarones/modules/ @maribakulj
|
| 40 |
+
|
| 41 |
+
# ──────────────────────────────────────────────────────────────────
|
| 42 |
+
# Cercle 3 — rapport, web, CLI, extras.
|
| 43 |
+
# ──────────────────────────────────────────────────────────────────
|
| 44 |
+
/picarones/report/ @maribakulj
|
| 45 |
+
/picarones/web/ @maribakulj
|
| 46 |
+
/picarones/cli/ @maribakulj
|
| 47 |
+
/picarones/extras/ @maribakulj
|
| 48 |
+
|
| 49 |
+
# ──────────────────────────────────────────────────────────────────
|
| 50 |
+
# Documentation, gouvernance, sécurité, accessibilité.
|
| 51 |
+
# Idéalement co-revue par un domain expert quand l'équipe s'étoffe.
|
| 52 |
+
# ──────────────────────────────────────────────────────────────────
|
| 53 |
+
/docs/ @maribakulj
|
| 54 |
+
/docs/case-studies/ @maribakulj # à co-revoir avec un archiviste/paléographe quand recruté
|
| 55 |
+
/docs/operations/ @maribakulj
|
| 56 |
+
/SECURITY.md @maribakulj
|
| 57 |
+
/ACCESSIBILITY.md @maribakulj # à co-revoir avec référent a11y
|
| 58 |
+
/GOVERNANCE.md @maribakulj
|
| 59 |
+
/CONTRIBUTING.md @maribakulj
|
| 60 |
+
/CODE_OF_CONDUCT.md @maribakulj
|
| 61 |
+
/CITATION.cff @maribakulj # ajouté Sprint A12
|
| 62 |
+
/paper.md @maribakulj # ajouté Sprint A12 (JOSS)
|
| 63 |
+
|
| 64 |
+
# ──────────────────────────────────────────────────────────────────
|
| 65 |
+
# Fichiers de configuration projet — revue renforcée car affectent
|
| 66 |
+
# tout le pipeline.
|
| 67 |
+
# ──────────────────────────────────────────────────────────────────
|
| 68 |
+
/pyproject.toml @maribakulj
|
| 69 |
+
/Dockerfile @maribakulj
|
| 70 |
+
/.github/ @maribakulj
|
| 71 |
+
/.github/workflows/ @maribakulj
|
| 72 |
+
/.github/CODEOWNERS @maribakulj
|
| 73 |
+
/Makefile @maribakulj
|
| 74 |
+
/requirements*.txt @maribakulj
|
| 75 |
+
/requirements*.lock @maribakulj
|
| 76 |
+
/picarones.spec @maribakulj
|
|
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Code de conduite — Picarones
|
| 2 |
+
|
| 3 |
+
> Sprint A10 du plan de remédiation institutionnelle. Adoption du
|
| 4 |
+
> [Contributor Covenant version 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).
|
| 5 |
+
|
| 6 |
+
## Notre engagement
|
| 7 |
+
|
| 8 |
+
En tant que membres, contributeurs et responsables, nous nous
|
| 9 |
+
engageons à faire de la participation à notre projet et à notre
|
| 10 |
+
communauté une expérience exempte de harcèlement pour tout le
|
| 11 |
+
monde, indépendamment de l'âge, de la taille corporelle, du
|
| 12 |
+
handicap visible ou invisible, de l'origine ethnique, des
|
| 13 |
+
caractéristiques sexuelles, de l'identité et de l'expression de
|
| 14 |
+
genre, du niveau d'expérience, de l'éducation, du statut socio-
|
| 15 |
+
économique, de la nationalité, de l'apparence personnelle, de la
|
| 16 |
+
race, de la religion, ou de l'identité et de l'orientation
|
| 17 |
+
sexuelles.
|
| 18 |
+
|
| 19 |
+
Nous nous engageons à agir et à interagir de manière à contribuer
|
| 20 |
+
à une communauté ouverte, accueillante, diverse, inclusive et
|
| 21 |
+
saine.
|
| 22 |
+
|
| 23 |
+
## Nos standards
|
| 24 |
+
|
| 25 |
+
Exemples de comportements qui contribuent à un environnement
|
| 26 |
+
positif :
|
| 27 |
+
|
| 28 |
+
- Faire preuve d'empathie et de bienveillance envers autrui.
|
| 29 |
+
- Respecter les opinions, points de vue et expériences différents.
|
| 30 |
+
- Donner et accepter avec grâce les commentaires constructifs.
|
| 31 |
+
- Assumer ses responsabilités et présenter des excuses aux
|
| 32 |
+
personnes affectées par nos erreurs, et apprendre de l'expérience.
|
| 33 |
+
- Se concentrer sur ce qui est le mieux non seulement pour nous en
|
| 34 |
+
tant qu'individus, mais aussi pour la communauté dans son ensemble.
|
| 35 |
+
|
| 36 |
+
Exemples de comportements inacceptables :
|
| 37 |
+
|
| 38 |
+
- L'usage d'un langage ou d'images sexualisés, et toute attention
|
| 39 |
+
ou avance sexuelle.
|
| 40 |
+
- Le trolling, les commentaires insultants ou désobligeants, et
|
| 41 |
+
les attaques personnelles ou politiques.
|
| 42 |
+
- Le harcèlement public ou privé.
|
| 43 |
+
- La publication d'informations privées d'autrui — telles qu'une
|
| 44 |
+
adresse physique ou de courrier électronique — sans leur
|
| 45 |
+
permission explicite.
|
| 46 |
+
- Toute autre conduite qui pourrait raisonnablement être considérée
|
| 47 |
+
comme inappropriée dans un cadre professionnel.
|
| 48 |
+
|
| 49 |
+
## Responsabilités de mise en œuvre
|
| 50 |
+
|
| 51 |
+
Les responsables de la communauté ont la responsabilité de
|
| 52 |
+
clarifier et de faire respecter nos normes de comportement
|
| 53 |
+
acceptable et prendront des mesures correctives appropriées et
|
| 54 |
+
équitables en réponse à tout comportement qu'ils jugent
|
| 55 |
+
inapproprié, menaçant, offensant ou nuisible.
|
| 56 |
+
|
| 57 |
+
Les responsables de la communauté ont le droit et la
|
| 58 |
+
responsabilité de supprimer, modifier ou rejeter les commentaires,
|
| 59 |
+
commits, code, modifications de wiki, issues, et autres
|
| 60 |
+
contributions qui ne sont pas alignés sur ce code de conduite, et
|
| 61 |
+
communiqueront les raisons des décisions de modération lorsque cela
|
| 62 |
+
sera approprié.
|
| 63 |
+
|
| 64 |
+
## Portée
|
| 65 |
+
|
| 66 |
+
Ce code de conduite s'applique à tous les espaces du projet, et
|
| 67 |
+
s'applique également lorsqu'un individu représente officiellement
|
| 68 |
+
le projet ou sa communauté dans des espaces publics. Les exemples
|
| 69 |
+
de représentation de notre communauté incluent l'utilisation d'une
|
| 70 |
+
adresse électronique officielle, la publication via un compte de
|
| 71 |
+
médias sociaux officiel, ou le rôle d'agent désigné lors d'un
|
| 72 |
+
événement en ligne ou hors ligne.
|
| 73 |
+
|
| 74 |
+
## Application
|
| 75 |
+
|
| 76 |
+
Les cas de comportement abusif, harcelant ou autrement inacceptable
|
| 77 |
+
peuvent être signalés au mainteneur principal via :
|
| 78 |
+
|
| 79 |
+
- une issue GitHub privée (étiquette `code-of-conduct`) ;
|
| 80 |
+
- un message direct à [@maribakulj](https://github.com/maribakulj) ;
|
| 81 |
+
- pour les cas graves : le défenseur des droits (France) —
|
| 82 |
+
<https://www.defenseurdesdroits.fr/>.
|
| 83 |
+
|
| 84 |
+
Toutes les plaintes seront examinées et étudiées rapidement et
|
| 85 |
+
équitablement.
|
| 86 |
+
|
| 87 |
+
Tous les responsables de la communauté sont tenus de respecter la
|
| 88 |
+
vie privée et la sécurité du rapporteur de tout incident.
|
| 89 |
+
|
| 90 |
+
## Lignes directrices d'application
|
| 91 |
+
|
| 92 |
+
Les responsables de la communauté suivront ces lignes directrices
|
| 93 |
+
sur l'impact communautaire pour déterminer les conséquences de
|
| 94 |
+
toute action qu'ils jugeront contraire à ce code de conduite :
|
| 95 |
+
|
| 96 |
+
### 1. Correction
|
| 97 |
+
|
| 98 |
+
**Impact communautaire** : utilisation d'un langage inapproprié ou
|
| 99 |
+
d'autres comportements jugés non professionnels ou indésirables.
|
| 100 |
+
|
| 101 |
+
**Conséquence** : un avertissement écrit privé de la part des
|
| 102 |
+
responsables de la communauté, clarifiant la nature de la violation
|
| 103 |
+
et expliquant pourquoi le comportement était inapproprié. Des
|
| 104 |
+
excuses publiques peuvent être demandées.
|
| 105 |
+
|
| 106 |
+
### 2. Avertissement
|
| 107 |
+
|
| 108 |
+
**Impact communautaire** : violation par un seul incident ou une
|
| 109 |
+
série d'actions.
|
| 110 |
+
|
| 111 |
+
**Conséquence** : avertissement avec conséquences pour la poursuite
|
| 112 |
+
du comportement. Aucune interaction avec les personnes impliquées,
|
| 113 |
+
y compris les interactions non sollicitées avec celles qui font
|
| 114 |
+
respecter le code de conduite, pendant une période donnée.
|
| 115 |
+
|
| 116 |
+
### 3. Bannissement temporaire
|
| 117 |
+
|
| 118 |
+
**Impact communautaire** : violation grave des normes de la
|
| 119 |
+
communauté, y compris un comportement inapproprié soutenu.
|
| 120 |
+
|
| 121 |
+
**Conséquence** : bannissement temporaire de toute interaction ou
|
| 122 |
+
communication publique avec la communauté pendant une période
|
| 123 |
+
donnée.
|
| 124 |
+
|
| 125 |
+
### 4. Bannissement permanent
|
| 126 |
+
|
| 127 |
+
**Impact communautaire** : démontrer un schéma de violation des
|
| 128 |
+
normes communautaires, y compris un comportement inapproprié
|
| 129 |
+
soutenu, le harcèlement d'un individu, ou l'agression ou le
|
| 130 |
+
dénigrement de catégories d'individus.
|
| 131 |
+
|
| 132 |
+
**Conséquence** : bannissement permanent de toute interaction
|
| 133 |
+
publique au sein du projet.
|
| 134 |
+
|
| 135 |
+
## Attribution
|
| 136 |
+
|
| 137 |
+
Ce code de conduite est adapté du
|
| 138 |
+
[Contributor Covenant](https://www.contributor-covenant.org), version
|
| 139 |
+
2.1, disponible à
|
| 140 |
+
<https://www.contributor-covenant.org/version/2/1/code_of_conduct.html>.
|
| 141 |
+
|
| 142 |
+
Les lignes directrices d'application sur l'impact communautaire ont
|
| 143 |
+
été inspirées par
|
| 144 |
+
[l'échelle d'application du code de conduite de Mozilla](https://github.com/mozilla/diversity).
|
| 145 |
+
|
| 146 |
+
Pour les réponses aux questions courantes sur ce code de conduite,
|
| 147 |
+
voir la FAQ à <https://www.contributor-covenant.org/faq>. Des
|
| 148 |
+
traductions sont disponibles à
|
| 149 |
+
<https://www.contributor-covenant.org/translations>.
|
|
@@ -0,0 +1,205 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Gouvernance — Picarones
|
| 2 |
+
|
| 3 |
+
> Sprint A10 du plan de remédiation institutionnelle
|
| 4 |
+
> ([`docs/audits/remediation-plan-2026-05.md`](docs/audits/remediation-plan-2026-05.md)).
|
| 5 |
+
>
|
| 6 |
+
> Ce document explicite **comment Picarones est maintenu et fait
|
| 7 |
+
> évoluer** : qui décide, à quelle cadence, avec quels engagements de
|
| 8 |
+
> service. Il complète :
|
| 9 |
+
>
|
| 10 |
+
> - [`CONTRIBUTING.md`](CONTRIBUTING.md) — comment contribuer
|
| 11 |
+
> techniquement (branches, tests, style) ;
|
| 12 |
+
> - [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) — comportement attendu
|
| 13 |
+
> dans les espaces du projet ;
|
| 14 |
+
> - [`SECURITY.md`](SECURITY.md) — signalement de vulnérabilités ;
|
| 15 |
+
> - [`.github/CODEOWNERS`](.github/CODEOWNERS) — qui est reviewer par
|
| 16 |
+
> défaut sur quel chemin.
|
| 17 |
+
|
| 18 |
+
## Rôles
|
| 19 |
+
|
| 20 |
+
### BDFL / Maintainer principal
|
| 21 |
+
|
| 22 |
+
À ce stade du projet (mai 2026, ~3 600 tests, 1.x), **Picarones
|
| 23 |
+
est maintenu en BDFL** par
|
| 24 |
+
[@maribakulj](https://github.com/maribakulj). Toute décision finale
|
| 25 |
+
sur les contrats d'API publique, les choix éditoriaux (palette,
|
| 26 |
+
règle de neutralité du moteur narratif, conventions de
|
| 27 |
+
normalisation) et les releases lui incombe.
|
| 28 |
+
|
| 29 |
+
### Reviewers
|
| 30 |
+
|
| 31 |
+
Tout collaborateur qui a contribué au moins **3 PR mergées** en
|
| 32 |
+
6 mois peut être ajouté à `.github/CODEOWNERS` comme reviewer sur
|
| 33 |
+
les paths qu'il connaît bien. La promotion est sur invitation par
|
| 34 |
+
le BDFL après accord du contributeur.
|
| 35 |
+
|
| 36 |
+
### Domain experts
|
| 37 |
+
|
| 38 |
+
Pour les sujets qui exigent une expertise non-tech :
|
| 39 |
+
|
| 40 |
+
- **Paléographie / archivistique** : cas d'études, prompts médiévaux,
|
| 41 |
+
glossaire historique, profils de normalisation diplomatique.
|
| 42 |
+
- **Accessibilité** : déclarations RGAA, audits manuels NVDA/VoiceOver,
|
| 43 |
+
retours WCAG.
|
| 44 |
+
- **Linguistique computationnelle** : métriques NER, taxonomies
|
| 45 |
+
d'erreurs, recherchabilité fuzzy.
|
| 46 |
+
|
| 47 |
+
Ces personnes sont nommées dans `CODEOWNERS` sur les chemins qui
|
| 48 |
+
les concernent et leur revue est **systématique** — pas pour bloquer
|
| 49 |
+
le merge mais pour garantir la qualité éditoriale.
|
| 50 |
+
|
| 51 |
+
### Évolution vers un comité de pilotage
|
| 52 |
+
|
| 53 |
+
Si Picarones atteint **> 5 mainteneurs actifs** ou **> 5 institutions
|
| 54 |
+
adoptantes documentées**, la gouvernance bascule en comité de pilotage
|
| 55 |
+
(steering committee) avec un vote à la majorité simple sur :
|
| 56 |
+
|
| 57 |
+
- ajout/retrait d'un mainteneur ;
|
| 58 |
+
- ruptures d'API publique (breaking changes au-delà d'un tag majeur) ;
|
| 59 |
+
- changement de licence ;
|
| 60 |
+
- évolution majeure de la philosophie éditoriale (neutralité du
|
| 61 |
+
rapport, ouverture aux modules contribués externes).
|
| 62 |
+
|
| 63 |
+
Cette évolution sera entérinée par une PR sur ce fichier signée par
|
| 64 |
+
tous les mainteneurs actifs.
|
| 65 |
+
|
| 66 |
+
## Cadence de release
|
| 67 |
+
|
| 68 |
+
| Type | Cadence cible | Déclencheur |
|
| 69 |
+
|---|---|---|
|
| 70 |
+
| **Patch** (1.2.x) | À la demande | Bug fix, correctif sécurité, doc |
|
| 71 |
+
| **Mineure** (1.x.0) | Mensuelle | Sortie d'au moins un sprint d'audit ou d'un nouveau feature group |
|
| 72 |
+
| **Majeure** (x.0.0) | Trimestrielle | Breaking changes API publique cumulés |
|
| 73 |
+
| **Hotfix sécurité** | < 72 h | CVE critique, problème de confidentialité |
|
| 74 |
+
|
| 75 |
+
La cadence est un objectif, pas un engagement contractuel. Une
|
| 76 |
+
release mineure peut être reportée si le travail planifié n'est pas
|
| 77 |
+
prêt — la stabilité prime sur le calendrier.
|
| 78 |
+
|
| 79 |
+
Procédure release détaillée :
|
| 80 |
+
[`docs/operations/release-process.md`](docs/operations/release-process.md).
|
| 81 |
+
|
| 82 |
+
## SLO de réponse
|
| 83 |
+
|
| 84 |
+
| Type d'événement | SLO en jours ouvrés |
|
| 85 |
+
|---|---|
|
| 86 |
+
| Triage initial d'une issue | 5 |
|
| 87 |
+
| Réponse à une PR (1ère revue) | 7 |
|
| 88 |
+
| Triage initial d'une faille de sécurité (cf. SECURITY.md) | 2 |
|
| 89 |
+
| Correctif d'une faille HIGH/CRITICAL | 5 |
|
| 90 |
+
| Release patch après correctif sécurité | 3 |
|
| 91 |
+
|
| 92 |
+
Ces SLO sont **best-effort** : Picarones est maintenu sur du temps
|
| 93 |
+
disponible, sans garantie commerciale. Pour des SLO contractualisés,
|
| 94 |
+
contractualiser un support institutionnel via une convention de
|
| 95 |
+
prestation (cf. modalités à définir au cas par cas).
|
| 96 |
+
|
| 97 |
+
## Politique de breaking changes
|
| 98 |
+
|
| 99 |
+
L'API publique de Picarones est définie par
|
| 100 |
+
[`docs/api-stable.md`](docs/api-stable.md). Elle inclut :
|
| 101 |
+
|
| 102 |
+
- les symboles ré-exportés depuis `picarones/__init__.py` ;
|
| 103 |
+
- les commandes CLI `picarones X` documentées dans le README ;
|
| 104 |
+
- les endpoints HTTP listés dans le README ;
|
| 105 |
+
- la structure du JSON de résultats (`BenchmarkResult.as_dict()`).
|
| 106 |
+
|
| 107 |
+
**Garanties** :
|
| 108 |
+
|
| 109 |
+
- À l'intérieur d'un tag majeur (`1.x`), aucun de ces contrats ne
|
| 110 |
+
change de manière incompatible.
|
| 111 |
+
- Une dépréciation est annoncée au moins **2 versions mineures**
|
| 112 |
+
avant suppression, avec `DeprecationWarning` à l'appel et entrée
|
| 113 |
+
dans le `CHANGELOG.md` en section *Deprecated*.
|
| 114 |
+
- Un breaking change exige un bump majeur (`1.x → 2.0`) et une
|
| 115 |
+
section *BREAKING CHANGES* dans la release notes.
|
| 116 |
+
|
| 117 |
+
Hors API publique (modules internes, helpers privés `_*`) : aucune
|
| 118 |
+
garantie de stabilité — utiliser à vos risques.
|
| 119 |
+
|
| 120 |
+
## Procédure de transfert de mainteneur
|
| 121 |
+
|
| 122 |
+
Si le BDFL doit transférer la maintenance (départ, indisponibilité
|
| 123 |
+
prolongée, conflit d'intérêt apparu) :
|
| 124 |
+
|
| 125 |
+
1. **Annonce** : issue publique sur le repo + entrée CHANGELOG.
|
| 126 |
+
2. **Période de transition** (≥ 3 mois) : nouveau mainteneur en
|
| 127 |
+
shadow review, le BDFL valide.
|
| 128 |
+
3. **Bascule** : transfert des droits GitHub (admin), update de
|
| 129 |
+
`CODEOWNERS`, update du `CITATION.cff` (auteurs).
|
| 130 |
+
4. **Communication** : annonce à la communauté HuggingFace Space,
|
| 131 |
+
PyPI, et institutions adoptantes connues.
|
| 132 |
+
|
| 133 |
+
Si aucun successeur n'est trouvé en 6 mois, le projet entre en
|
| 134 |
+
**mode archive** : tag `archived: 2026-XX`, dernière release de
|
| 135 |
+
sécurité, README enrichi d'un encart « projet en cherche d'un
|
| 136 |
+
nouveau mainteneur — fork bienvenu ».
|
| 137 |
+
|
| 138 |
+
## Conflicts of interest (Sprint A10, M-10)
|
| 139 |
+
|
| 140 |
+
Picarones benchmarke des fournisseurs cloud commerciaux (OpenAI,
|
| 141 |
+
Anthropic, Mistral, Google, Microsoft Azure). Pour qu'un papier ou
|
| 142 |
+
une étude qui s'appuie sur ses analyses Pareto coût soit citable
|
| 143 |
+
sans suspicion, nous déclarons :
|
| 144 |
+
|
| 145 |
+
### Affiliations des mainteneurs
|
| 146 |
+
|
| 147 |
+
Les mainteneurs déclarent leurs affiliations académiques et
|
| 148 |
+
industrielles dans la liste suivante (mise à jour à chaque ajout
|
| 149 |
+
de mainteneur dans `CODEOWNERS`) :
|
| 150 |
+
|
| 151 |
+
- **@maribakulj** : aucune affiliation salariée chez un fournisseur
|
| 152 |
+
OCR/LLM/cloud benchmarké par Picarones. Aucune participation
|
| 153 |
+
capitalistique dans une entreprise concurrente ou cliente d'un
|
| 154 |
+
des fournisseurs.
|
| 155 |
+
|
| 156 |
+
### Indépendance des données de pricing
|
| 157 |
+
|
| 158 |
+
Les valeurs dans `picarones/data/pricing.yaml` :
|
| 159 |
+
|
| 160 |
+
- proviennent **exclusivement** des tarifs publics affichés sur les
|
| 161 |
+
sites des fournisseurs (sans NDA, sans accord commercial) ;
|
| 162 |
+
- sont datées explicitement (`meta.last_updated`, `meta.valid_until`
|
| 163 |
+
depuis Sprint A8) ;
|
| 164 |
+
- peuvent être surchargées par l'utilisateur via
|
| 165 |
+
`ReportGenerator(..., pricing=...)` pour refléter ses propres
|
| 166 |
+
tarifs négociés.
|
| 167 |
+
|
| 168 |
+
Aucun fournisseur ne finance, sponsorise ou influence le contenu
|
| 169 |
+
de cette table. Si un fournisseur souhaite corriger une valeur, il
|
| 170 |
+
doit ouvrir une PR publique avec source vérifiable.
|
| 171 |
+
|
| 172 |
+
### Indépendance éditoriale du moteur narratif
|
| 173 |
+
|
| 174 |
+
Le moteur narratif (Sprint 19+) émet des `Fact` traçables au JSON
|
| 175 |
+
d'entrée. Aucune logique privilégie un fournisseur sur un autre :
|
| 176 |
+
|
| 177 |
+
- les seuils des détecteurs sont éditoriaux (publics dans
|
| 178 |
+
`core/facts.py`) et symétriques entre moteurs ;
|
| 179 |
+
- la philosophie « Picarones mesure et classe — il ne tranche pas »
|
| 180 |
+
garantit l'absence de recommandation prescriptive.
|
| 181 |
+
|
| 182 |
+
Toute évolution de cette politique exige un PR signé par la
|
| 183 |
+
totalité des mainteneurs actifs.
|
| 184 |
+
|
| 185 |
+
### Sponsoring et financement
|
| 186 |
+
|
| 187 |
+
Si Picarones reçoit un jour un financement institutionnel ou
|
| 188 |
+
commercial (subvention, prestation, sponsorship), le donateur sera
|
| 189 |
+
listé en pied du `README.md` avec mention explicite « Picarones
|
| 190 |
+
n'est pas obligé envers ses sponsors et conserve son indépendance
|
| 191 |
+
éditoriale ». Toute restriction d'usage demandée par un sponsor
|
| 192 |
+
sera publiquement refusée et déclenchera l'annulation du sponsoring.
|
| 193 |
+
|
| 194 |
+
## Ressources
|
| 195 |
+
|
| 196 |
+
- [`CONTRIBUTING.md`](CONTRIBUTING.md) — guide technique pour PR
|
| 197 |
+
- [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) — Contributor Covenant 2.1
|
| 198 |
+
- [`SECURITY.md`](SECURITY.md) — signalement de vulnérabilités
|
| 199 |
+
- [`ACCESSIBILITY.md`](ACCESSIBILITY.md) — engagement WCAG 2.1 AA
|
| 200 |
+
- [`docs/operations/release-process.md`](docs/operations/release-process.md)
|
| 201 |
+
— cycle de release
|
| 202 |
+
|
| 203 |
+
---
|
| 204 |
+
|
| 205 |
+
*Dernière mise à jour : 2 mai 2026 (Sprint A10).*
|
|
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Tests Sprint A10 — gouvernance institutionnelle (M-10 + M-11).
|
| 2 |
+
|
| 3 |
+
Garde-fou : les 6 fichiers de gouvernance doivent exister, ne pas
|
| 4 |
+
être vides, et couvrir les sections clés. Empêche une suppression
|
| 5 |
+
accidentelle ou un PR qui viderait l'un d'eux par inadvertance.
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
from __future__ import annotations
|
| 9 |
+
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
|
| 12 |
+
import pytest
|
| 13 |
+
|
| 14 |
+
REPO_ROOT = Path(__file__).resolve().parents[2]
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
GOVERNANCE_FILES = [
|
| 18 |
+
"CODEOWNERS", # cherché à la racine ET dans .github/
|
| 19 |
+
"GOVERNANCE.md",
|
| 20 |
+
"CODE_OF_CONDUCT.md",
|
| 21 |
+
"SECURITY.md", # pré-existant (Sprint 24)
|
| 22 |
+
"ACCESSIBILITY.md", # Sprint A7
|
| 23 |
+
"LICENSE", # pré-existant
|
| 24 |
+
"CONTRIBUTING.md", # pré-existant (Sprint 30)
|
| 25 |
+
]
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def _resolve(name: str) -> Path | None:
|
| 29 |
+
"""Cherche un fichier à la racine, dans ``.github/`` ou ``docs/``."""
|
| 30 |
+
candidates = [
|
| 31 |
+
REPO_ROOT / name,
|
| 32 |
+
REPO_ROOT / ".github" / name,
|
| 33 |
+
REPO_ROOT / "docs" / name,
|
| 34 |
+
]
|
| 35 |
+
for c in candidates:
|
| 36 |
+
if c.exists():
|
| 37 |
+
return c
|
| 38 |
+
return None
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
@pytest.mark.parametrize("name", GOVERNANCE_FILES)
|
| 42 |
+
def test_governance_file_exists(name: str) -> None:
|
| 43 |
+
"""Chaque fichier de gouvernance doit exister."""
|
| 44 |
+
path = _resolve(name)
|
| 45 |
+
assert path is not None, (
|
| 46 |
+
f"{name} introuvable — recherché à racine/, .github/, docs/."
|
| 47 |
+
)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
@pytest.mark.parametrize("name", GOVERNANCE_FILES)
|
| 51 |
+
def test_governance_file_not_empty(name: str) -> None:
|
| 52 |
+
"""Chaque fichier de gouvernance doit avoir un contenu non trivial
|
| 53 |
+
(≥ 200 octets — un README dégradé serait < 100 octets)."""
|
| 54 |
+
path = _resolve(name)
|
| 55 |
+
if path is None:
|
| 56 |
+
pytest.skip(f"{name} absent — couvert par test_governance_file_exists")
|
| 57 |
+
assert path.stat().st_size >= 200, (
|
| 58 |
+
f"{path.name} fait seulement {path.stat().st_size} octets — "
|
| 59 |
+
"fichier vide ou tronqué."
|
| 60 |
+
)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def test_codeowners_has_catchall() -> None:
|
| 64 |
+
"""``.github/CODEOWNERS`` doit avoir une ligne catch-all ``* @user``
|
| 65 |
+
pour qu'aucun chemin ne soit sans reviewer."""
|
| 66 |
+
f = REPO_ROOT / ".github" / "CODEOWNERS"
|
| 67 |
+
assert f.exists()
|
| 68 |
+
text = f.read_text(encoding="utf-8")
|
| 69 |
+
# Ligne qui commence par `*` suivi d'au moins un @
|
| 70 |
+
has_catchall = any(
|
| 71 |
+
line.strip().startswith("*") and "@" in line
|
| 72 |
+
for line in text.splitlines()
|
| 73 |
+
if not line.strip().startswith("#") and line.strip()
|
| 74 |
+
)
|
| 75 |
+
assert has_catchall, (
|
| 76 |
+
"CODEOWNERS doit contenir une ligne catch-all `* @user` "
|
| 77 |
+
"pour garantir un reviewer par défaut."
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def test_governance_documents_release_cadence() -> None:
|
| 82 |
+
"""``GOVERNANCE.md`` doit documenter la cadence de release."""
|
| 83 |
+
f = REPO_ROOT / "GOVERNANCE.md"
|
| 84 |
+
text = f.read_text(encoding="utf-8")
|
| 85 |
+
for keyword in ["Patch", "Mineure", "Majeure", "release", "SLO"]:
|
| 86 |
+
assert keyword in text, (
|
| 87 |
+
f"GOVERNANCE.md doit mentionner la notion `{keyword}`"
|
| 88 |
+
)
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def test_governance_documents_coi() -> None:
|
| 92 |
+
"""``GOVERNANCE.md`` doit contenir une section Conflicts of interest
|
| 93 |
+
(item M-10 de l'audit)."""
|
| 94 |
+
f = REPO_ROOT / "GOVERNANCE.md"
|
| 95 |
+
text = f.read_text(encoding="utf-8")
|
| 96 |
+
# Cherche l'une des formulations acceptables
|
| 97 |
+
coi_markers = [
|
| 98 |
+
"Conflicts of interest",
|
| 99 |
+
"Conflits d'intérêt",
|
| 100 |
+
"indépendance",
|
| 101 |
+
"Affiliations des mainteneurs",
|
| 102 |
+
]
|
| 103 |
+
found = [m for m in coi_markers if m in text]
|
| 104 |
+
assert found, (
|
| 105 |
+
f"GOVERNANCE.md doit contenir une section COI. "
|
| 106 |
+
f"Aucun marqueur trouvé parmi {coi_markers}."
|
| 107 |
+
)
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
def test_coi_mentions_pricing_independence() -> None:
|
| 111 |
+
"""La section COI doit explicitement traiter l'indépendance des
|
| 112 |
+
données de pricing vis-à-vis des fournisseurs benchmarkés."""
|
| 113 |
+
f = REPO_ROOT / "GOVERNANCE.md"
|
| 114 |
+
text = f.read_text(encoding="utf-8")
|
| 115 |
+
assert "pricing" in text.lower()
|
| 116 |
+
# Doit mentionner au moins un fournisseur cloud benchmarké
|
| 117 |
+
providers = ["OpenAI", "Anthropic", "Mistral", "Google", "Azure"]
|
| 118 |
+
found = [p for p in providers if p in text]
|
| 119 |
+
assert len(found) >= 3, (
|
| 120 |
+
f"COI doit citer ≥ 3 fournisseurs cloud benchmarkés ; "
|
| 121 |
+
f"trouvé : {found}"
|
| 122 |
+
)
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
def test_code_of_conduct_uses_contributor_covenant() -> None:
|
| 126 |
+
"""``CODE_OF_CONDUCT.md`` doit s'appuyer sur Contributor Covenant
|
| 127 |
+
(standard de facto, traduit en 30+ langues)."""
|
| 128 |
+
f = REPO_ROOT / "CODE_OF_CONDUCT.md"
|
| 129 |
+
text = f.read_text(encoding="utf-8")
|
| 130 |
+
assert "Contributor Covenant" in text
|
| 131 |
+
# Doit mentionner les 4 niveaux d'application standard
|
| 132 |
+
levels = ["Correction", "Avertissement", "Bannissement"]
|
| 133 |
+
for level in levels:
|
| 134 |
+
assert level in text, f"CoC doit décrire le niveau `{level}`"
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
def test_governance_links_other_docs() -> None:
|
| 138 |
+
"""``GOVERNANCE.md`` doit lier les autres docs de gouvernance pour
|
| 139 |
+
cohérence du système."""
|
| 140 |
+
f = REPO_ROOT / "GOVERNANCE.md"
|
| 141 |
+
text = f.read_text(encoding="utf-8")
|
| 142 |
+
expected_links = [
|
| 143 |
+
"CONTRIBUTING.md",
|
| 144 |
+
"CODE_OF_CONDUCT.md",
|
| 145 |
+
"SECURITY.md",
|
| 146 |
+
"ACCESSIBILITY.md",
|
| 147 |
+
]
|
| 148 |
+
missing = [link for link in expected_links if link not in text]
|
| 149 |
+
assert not missing, (
|
| 150 |
+
f"GOVERNANCE.md doit linker : {missing}"
|
| 151 |
+
)
|