Files
college-infos/AGENTS.md
Antoine Van Elstraete aaca78c55d docs+fix: renforcement de l'architecture agentique et corrections de sécurité
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>
2026-09-05 23:52:02 +02:00

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 (mode strict=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.md pour 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 : mypy en mode strict=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 utilisent frozen=True.

Architecture

  • Injection de dépendances : Utiliser typing.Protocol et une composition root dans pipeline/run.py. Interdiction des singletons globaux.

Style

  • Longueur de ligne : 100 caractères maximum (configuré dans ruff).
  • Imports : Triés automatiquement par ruff (intègre isort).

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(), et redact_exception() depuis utils/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.example comme 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 @coder pour 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

  1. Lire la demande, TODO.md, git status et les fichiers concernés.
  2. Préserver les changements existants de l'utilisateur.
  3. Pour une correction, reproduire d'abord le défaut avec un test automatisé lorsque c'est raisonnable.
  4. Faire une modification étroite et cohérente, en respectant les conventions du projet (idempotence, mode dégradé, repli iCal/pronotepy).
  5. 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.
  6. Mettre à jour la documentation et les exemples dans le même changement si leur comportement public évolue.
  7. Cocher dans TODO.md uniquement les éléments entièrement réalisés et validés.
  8. 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, chore ou refactor.
  • Partir de l'état validé de la branche principale (main ou dev), 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).