Files
Copies/Architecture.org
T
2026-08-22 13:17:54 +02:00

125 lines
5.3 KiB
Org Mode

#+title: Architecture et conventions de développement
#+author: Sébastien Miquel
#+date: 22-08-2026
#+OPTIONS:
Ce document décrit les invariants techniques du projet. Il s'adresse
aux développeurs et aux agents logiciels qui modifient le dépôt.
- [[file:Readme.org][Guide de démarrage]]
- [[file:Script.org][Référence des étapes et des scripts]]
* API commune pour les scripts
Le paquet =copienator= centralise les chemins d'une évaluation et les
écritures JSON sûres. Un script ne devrait donc plus reconstruire les
chemins partagés à la main :
#+BEGIN_SRC python
from copienator import EvaluationWorkspace, atomic_write_json
workspace = EvaluationWorkspace("Interro")
atomic_write_json(workspace.correction_file, corrections)
#+END_SRC
=EvaluationWorkspace.discover(path)= retrouve également la racine d'une
évaluation à partir d'un fichier ou d'un sous-dossier. Sa construction
ne crée aucun fichier. La création explicite de
=.copienator/logs/= et =.copienator/runs/= se fait avec
=workspace.ensure_control_directories()=. Le chemin
=.copienator/state.sqlite3= est réservé à une future couche d'état
transactionnelle.
=atomic_write_json= écrit d'abord dans un fichier temporaire situé dans
le même dossier, synchronise son contenu, puis remplace la destination.
Une interruption ne laisse donc pas un JSON partiellement écrit. Pour
une modification concurrente de type lire-modifier-écrire, utiliser
=atomic_update_json= : cet utilitaire protège l'opération complète avec
un verrou inter-processus Linux/Windows.
* Convention des scripts standardisés
Les scripts standardisés exposent =build_parser()=, =run(...)= et
=main(argv=None)=. Leur import ne lance aucun traitement. Ils acceptent
le dossier d'évaluation comme premier argument positionnel, utilisent
=EvaluationWorkspace= pour les chemins partagés et peuvent afficher la
trace complète d'une erreur avec =--verbose=.
Les codes de sortie communs sont :
| Code | Signification |
|------+---------------|
| 0 | réussite |
| 1 | erreur de traitement |
| 2 | arguments invalides |
| 3 | évaluation ou prérequis invalides |
| 4 | traitement partiel, avec avertissements |
| 130 | interruption par l'utilisateur |
Le GUI distingue notamment un traitement partiel d'un échec. Les
scripts migrés vers cette convention sont actuellement :
- =copies_tools.py=, =grouping.py= et =verify_groups.py= ;
- =post-correction.py= et =resolve_manual.py= ;
- =page_splitter.py=, =cutleft.py=, =plotting.py= et
=splitting_int.py= ;
- =gemini_for_labels.py= ;
- =gemini_for_enonce.py= et =enonce_info.py= ;
- =correction.py=, =submit_batches.py=, =batch_status.py= et
=fetch_batched_results.py= ;
- =annotating.py=, =annotating_with_checks.py= et
=annotating_by_label.py= ;
- =reading_annotations.py= et =reading_grouped_annotations.py= ;
- =export.py=, =import.py= et =giving_names.py=.
* Organisation du code
- Le paquet =copienator= contient les abstractions partagées par les
scripts, notamment =EvaluationWorkspace= et les écritures atomiques.
- Le paquet =copienator_gui= contient la définition du workflow, l'état
persistant, le lanceur de processus et l'application Tk.
- Les scripts situés à la racine restent des points d'entrée autonomes.
Leur import ne doit pas déclencher de traitement.
* État et exécution du GUI
L'état d'une évaluation est conservé dans =.copienator-gui.json=. Les
valeurs des arguments, le dernier mode exécuté, les statuts et un
historique borné y sont enregistrés atomiquement. Les sorties des
processus sont conservées dans =.copienator/logs/=. Le GUI lance les
scripts dans des processus séparés afin de pouvoir afficher leur sortie,
leur transmettre une saisie et les interrompre.
Les retours en arrière ne suppriment pas les artefacts. Ils marquent les
étapes suivantes comme étant à revalider. Les automatismes de première
visite sont également persistés et ne doivent pas être rejoués lors d'un
retour en arrière.
* Invariants à préserver
- Utiliser =EvaluationWorkspace= pour les chemins partagés d'une
évaluation au lieu de reconstruire ces chemins dans chaque script.
- Publier les JSON et les ensembles de fichiers importants de façon
atomique. Une interruption ou un résultat partiel doit conserver la
dernière sortie complète lorsqu'elle existe.
- Conserver la convention =build_parser()=, =run(...)= et
=main(argv=None)= pour les scripts standardisés.
- Ne lancer aucun traitement lors de l'import d'un module.
- Retourner les codes de sortie communs afin que le GUI distingue une
réussite, un résultat partiel, un échec et une interruption.
- Préserver les modifications manuelles et les fichiers déjà présents,
sauf lorsqu'une option explicite comme =--overwrite= ou =--reset=
autorise leur remplacement.
- Les labels deviennent des noms de fichiers. Ils doivent donc respecter
les contraintes de la plateforme, notamment l'interdiction de =:= sous
Windows.
* Règle de classement de la documentation
- Une information nécessaire pour installer ou démarrer l'application
appartient à [[file:Readme.org][Readme.org]].
- Une commande, un argument ou une étape du workflow appartient à
[[file:Script.org][Script.org]].
- Une convention interne, un invariant ou une décision d'architecture
appartient au présent document.