AGENTS.md :
- Rôles d'agents renforcés : @coder ne valide pas, @debugger ne code pas,
@verifier ne modifie pas, etc.
- Table « Séparation des rôles » : tâche → agent responsable → ne pas confier à
- Workflow étape 5 : délégation explicite à @verifier pour la validation
GUIDE_DEV_PYTHON.md :
- 7 notes « Décision d'implémentation » ajoutées aux sections concernées :
3.1.1 (XMPP_RECIPIENT→XMPP_TO, vars ajoutées), 3.1.2 (SYNC_PAST_DAYS→AppSettings),
3.2 (Pydantic v2 style, defaults corrigés), 4.2.1 (redact_exception module function),
4.2.2 (getLevelNamesMapping), 5.1.5 (normalize_pronote_uid, usedforsecurity=False),
6 (ConfigDict, StrEnum, alias _date, external_info Optional)
Sécurité (audit @security-auditor, corrections @coder, validation @verifier) :
- RedactingFormatter : redaction APRÈS formatage (corrige TypeError %s + fuite traceback)
- redact_url : masquage des credentials dans userinfo URL (HTTP Basic Auth)
- redact_secrets : patterns étendus (api_key, access_token, authorization, auth)
- redact_secrets : support JSON-style « key: value » avec guillemets
Validations (@verifier) :
- ruff check : PASS | mypy strict : PASS | bandit : PASS (0 issue)
- %s formatting : OK (password=REDACTED, pas de TypeError)
- Traceback redaction : OK (icalsecurise=REDACTED)
- URL userinfo : OK (user:REDACTED@host)
- JSON-style redaction : OK ({"token": "REDACTED"})
- Régression red-to-green : OK (historical HEAD reproduction)
Co-authored-by: OpenCode/orchestrator <opencode-orchestrator@agents.invalid>
12 KiB
Guide pour les agents et contributeurs — pronote-sync
Langue de travail : Français (ce fichier et toute la documentation projet).
1. Description du projet
pronote-sync est un pipeline Python qui synchronise les données de Pronote (système de gestion scolaire) vers CalDAV (agendas) et XMPP (notifications).
Spécification complète : Voir
GUIDE_DEV_PYTHON.md.
2. Stack technique
Langage et dépendances
- Python : ≥ 3.13 (actuellement 3.14 dans
.venv/) - Dépendances principales :
pydantic>=2.0,pydantic-settings,icalendar,caldav,slixmpp,pronotepy,feedparser,requests,httpx
Outils de développement
- Linter :
ruff(longueur de ligne : 100) - Typage :
mypy(modestrict=true) - Tests :
pytest(couverture ≥ 90%),pytest-mock,responses,aioresponses - Sécurité :
bandit - Pre-commit : hooks configurés pour
ruff,mypy,bandit
Environnement
- Virtualenv :
.venv/(à activer avant toute opération) - Fichier de configuration :
.env(à partir de.env.example)
3. Structure du projet
pronote_sync/
├── config/ # Configuration et paramètres
├── models/ # Modèles de données (Pydantic v2)
├── sources/ # Connecteurs (Pronote, iCal, etc.)
├── sync/ # Logique de synchronisation
├── synthesis/ # Génération de synthèses (IA)
├── channels/ # Canaux de sortie (CalDAV, XMPP)
├── pipeline/ # Orchestration du pipeline
├── utils/ # Utilitaires (redaction, logging, etc.)
├── cli/ # Interface en ligne de commande
└── __init__.py
tests/
├── fixtures/ # Données de test anonymisées
├── unit/ # Tests unitaires
└── integration/ # Tests d'intégration
Plan de développement : Voir
TODO.mdpour les 15 jalons (M1-M15).
4. Commandes essentielles
Environnement
# Activer le virtualenv
source .venv/bin/activate
# Installer les dépendances de développement
pip install -e ".[dev]"
Qualité de code
# Linter (ruff)
ruff check .
# Formattage (ruff)
ruff format .
# Vérification des types (mypy)
mypy .
# Analyse de sécurité (bandit)
bandit -r pronote_sync/
# Pre-commit (tous les hooks)
pre-commit run --all-files
Tests
# Exécuter les tests
pytest
# Exécuter les tests avec couverture
pytest --cov
CLI
# Exécuter en mode dry-run (simulation)
pronote-sync --dry-run
5. Conventions de code
Typage
- Strict :
mypyen modestrict=true. Tous les paramètres, retours et variables locales doivent être typés. - Pydantic v2 : Tous les modèles de données héritent de
BaseModel. Les modèles de contrat utilisentfrozen=True.
Architecture
- Injection de dépendances : Utiliser
typing.Protocolet une composition root danspipeline/run.py. Interdiction des singletons globaux.
Style
- Longueur de ligne : 100 caractères maximum (configuré dans
ruff). - Imports : Triés automatiquement par
ruff(intègreisort).
Tests
- Sans réseau : Utiliser uniquement des mocks (
pytest-mock,responses,aioresponses). - Fixtures : Les données de test doivent être anonymisées et stockées dans
tests/fixtures/.
Comportement
- Idempotence : Deux exécutions identiques sans changement externe doivent produire le même résultat.
- Mode dégradé :
- Si l'IA échoue → retourner un message sans synthèse.
- Si
pronotepyéchoue → fallback vers le parsing iCal. - Si tout échoue → lever une erreur explicite.
Documentation (docstrings)
- Obligatoire : Toute fonction, méthode et classe publique doit avoir une docstring.
- Format : Utiliser le format Sphinx/reST (pas Google ou NumPy) pour une compatibilité native avec Sphinx.
- Contenu :
- Une ligne de résumé courte (une phrase).
- Une description étendue optionnelle.
- Les paramètres avec
:param nom:. - Le retour avec
:return:et:rtype:. - Les exceptions avec
:raises TypeException:.
- Modules : Chaque module doit avoir une docstring au niveau module.
- Objectif : Générer une documentation PDF via LaTeX avec Sphinx.
Exemple :
def fetch_ical(url: str) -> str:
"""Récupère le contenu d'un flux iCal Pronote.
:param url: URL du flux iCal (avec token ``icalsecurise``).
:return: Contenu brut du flux iCal.
:rtype: str
:raises requests.RequestException: Si la requête HTTP échoue.
"""
6. Sécurité et secrets
Règles absolues
- Aucun secret en clair : Ni dans le code, ni dans les logs, ni dans les erreurs, ni dans les fixtures.
- Masquage : Utiliser systématiquement
redact_url(),redact_secrets(), etredact_exception()depuisutils/redaction.py.
Bonnes pratiques
- Types sécurisés : Les mots de passe et clés API doivent utiliser
pydantic.SecretStr. - Fichier
.env: Jamais committé (couvert par.gitignore). Utiliser.env.examplecomme template.
7. Plan de développement
Le projet suit un plan séquentiel en 15 jalons (M1-M15) décrits dans TODO.md.
- Chaque jalon a des critères d'acceptation à valider avant de passer au suivant.
- Ordre logique : scaffolding → config → modèles → sources → sync → synthèse → canaux → pipeline → CLI → tests → déploiement → docs
8. Référence
| Document | Rôle |
|---|---|
GUIDE_DEV_PYTHON.md |
Spécification complète (architecture, modèles, parsing, déploiement) |
TODO.md |
Plan de développement détaillé (15 jalons) |
9. Agents OpenCode
Cette section s'applique uniquement lorsque le travail est exécuté avec le système d'agents d'OpenCode.
Les rôles d'agents disponibles pour ce projet sont les suivants :
@architect: Arbitrages d'architecture et choix techniques structurants. Ne produit pas de code.@coder: Écrit et modifie du code, de la configuration et des scripts. Ne valide pas (ruff, mypy, pytest) — c'est le rôle de@verifier. Ne diagnostique pas — c'est le rôle de@debugger.@debugger: Reproduit un symptôme et établit sa cause profonde. Ne modifie pas le code.@explorer: Explore le dépôt en lecture seule. Ne modifie rien, n'exécute pas de commandes.@orchestrator: Compréhension globale, définition des jalons, coordination et garantie du résultat. N'écrit pas de code.@planner: Transforme une demande complexe en unités exécutables. Ne dirige aucun technicien.@reviewer: Revues indépendantes de correction, régression, contrats et maintenabilité. Ne modifie pas le code.@security-auditor: Audit indépendant d'une surface de sécurité. Ne modifie pas le code.@tech-writer: Rédige et maintient la documentation. N'écrit pas de code applicatif.@test-engineer: Conçoit, écrit et exécute des tests ciblés. N'écrit pas de code de production.@ui-designer: Conçoit et implémente les interfaces Web et terminal.@verifier: Vérifie indépendamment le comportement livré, les régressions et le respect des conventions (ruff, mypy, pytest, bandit, idempotence, mode dégradé). Ne modifie pas le code.@web-explorer: Recherche et extrait des sources Web vérifiables. Ne modifie pas le dépôt.
Note
: Ne pas utiliser
@coderpour les tâches de documentation (@tech-writer) ni pour les tests (@test-engineer).
Séparation des rôles
| Type de tâche | Agent responsable | Ne pas confier à |
|---|---|---|
| Écrire/modifier du code | @coder |
@verifier, @explorer |
| Valider (ruff, mypy, pytest, bandit) | @verifier |
@coder |
| Diagnostiquer un bug | @debugger |
@coder |
| Écrire un test | @test-engineer |
@coder |
| Rédiger de la documentation | @tech-writer |
@coder |
| Explorer le dépôt (lecture) | @explorer |
@coder, @verifier |
| Arbitrage technique structurant | @architect |
@coder, @planner |
| Revue de code | @reviewer |
@coder, @verifier |
| Audit de sécurité | @security-auditor |
@coder, @verifier |
| Recherche web | @web-explorer |
@explorer |
| Découpage de travail complexe | @planner |
@coder |
10. Workflow de modification
- Lire la demande,
TODO.md,git statuset les fichiers concernés. - Préserver les changements existants de l'utilisateur.
- Pour une correction, reproduire d'abord le défaut avec un test automatisé lorsque c'est raisonnable.
- Faire une modification étroite et cohérente, en respectant les conventions du projet (idempotence, mode dégradé, repli iCal/pronotepy).
- Faire vérifier le comportement par
@verifier(ruff, mypy, pytest, bandit) et les cas d'erreur, notamment :- Succès de la synchronisation Pronote → CalDAV/XMPP.
- Repli vers iCal en cas d'échec de
pronotepy. - Gestion des erreurs explicites.
- Mettre à jour la documentation et les exemples dans le même changement si leur comportement public évolue.
- Cocher dans
TODO.mduniquement les éléments entièrement réalisés et validés. - Terminer avec un handoff concis : fichiers modifiés, validations exécutées, limites et prochaine étape.
Pour les changements larges ou risqués : Produire d'abord un audit ou un aperçu. Règle de commit : Ne pas committer sans autorisation explicite. Une autorisation de commit ne vaut pas autorisation de push.
11. Branches et commits
- Une évolution cohérente se fait sur une branche dédiée.
- Nommer les branches selon le format
<type>/<sujet-en-kebab-case>, où<type>est l'un des suivants :feature,fix,docs,choreourefactor. - Partir de l'état validé de la branche principale (
mainoudev), sauf demande explicite. - Garder un commit atomique par objectif vérifiable. Utiliser les préfixes conventionnels pour les messages de commit :
feat:pour une nouvelle fonctionnalité.fix:pour une correction de bug.docs:pour une mise à jour de documentation.chore:pour une tâche de maintenance.refactor:pour une refactorisation de code.
- Quand un agent a contribué au changement, ajouter un trailer Git standard au commit :
Co-authored-by: <harness>/<modèle> <adresse@agents.invalid> - Avant un commit autorisé, vérifier :
git status(fichiers modifiés attendus).- Le diff complet (
git diff). - L'absence de secret ou de configuration locale dans le diff.
- Les validations pertinentes (
ruff,mypy,pytest,bandit). git diff --check(pas de problèmes d'espaces blancs).
- Après le commit, rapporter :
- Le hash du commit.
- Le contenu du commit.
- Les validations exécutées.
Règle absolue : Ne jamais pousser (
git push) sans demande distincte et explicite.
12. Définition de terminé
Un changement est considéré comme terminé lorsque :
- Le cas nominal et les échecs pertinents sont testés (ex. : synchronisation réussie, repli iCal, erreurs explicites).
- Les outils de validation (
ruff,mypy,pytest,bandit) passent sans erreur. - Aucun secret ni configuration locale n'apparaît dans le diff ou les fichiers suivis.
- La documentation reste cohérente avec le code (ex. : mise à jour des exemples, des contrats ou des décisions d'architecture).
- Le handoff distingue clairement :
- Ce qui a été vérifié localement (ex. : tests unitaires, linter).
- Ce qui nécessite encore une vérification manuelle (ex. : tests d'intégration avec un serveur CalDAV réel).