Règles métier¶
Les règles métier du modèle conceptuel. Chaque règle a un identifiant ancré (#r1 à #r35) qui sert de point de référence depuis le reste du dossier (parcours, stories, maquettes).
Site, point, passage¶
- R1 : un n° de carré est obligatoirement composé de 6 chiffres, dont les 2 premiers correspondent au numéro de département (avec leading zero pour les départements 1 à 9).
- R2 : un code de point est une lettre majuscule suivie d'un ou plusieurs chiffres (regex
[A-Z][0-9]+, ex.A1,Z4,Z41). Validation à la saisie : un code à plusieurs chiffres commeB100est donc accepté. - R3 : sur les sites en mode
PointFixeStandard(cf. C2), deux passages sont attendus par site et par année :- passage 1 : entre le 15 juin et le 31 juillet,
- passage 2 : entre le 15 août et le 30 septembre.
L'application doit alerter sans bloquer si l'utilisateur déclare un passage hors fenêtre. Sur les sites en mode
PointFixeRecherche(dates personnalisées pour des besoins recherche), cette règle est muette : aucune alerte n'est générée. Elle est également muette sur une nuit déclarée participation opportuniste (R34). État réel : la vérification de fenêtre est calculée (ServicePassage.verifierProtocole), mais sa restitution à l'utilisateur relève du solde de saison (#2349, #2356), non d'une alerte à la saisie : R3 est un indicateur de pilotage de la campagne, pas une garde de rattachement (arbitrage tracé en #2387).
- R4 : sur les sites en mode
PointFixeStandard, intervalle conseillé entre les deux passages d'un même point d'écoute : ≥ 1 mois (la vérification compare les passages d'un même point dans la même année). La clause « dates anniversaires (±10 j) d'une année à l'autre » n'est pas implémentée. Comme pour R3, cette vérification est calculée et sera restituée par le solde de saison (#2349), non par une alerte de saisie (arbitrage tracé en #2387). Sur les sites en modePointFixeRecherche, cette règle est également muette (l'utilisateur enregistre à la fréquence qui convient à son protocole, y compris plusieurs nuits successives), de même que sur une nuit déclarée participation opportuniste (R34). - R5 : le triplet
(Site, Point, Année, n° de passage)est unique : un même point ne peut pas avoir deux passages avec le même n° dans la même année. - R34 : une nuit peut être déclarée participation opportuniste : elle a bien été enregistrée, mais hors du protocole de l'observateur. R3 et R4 sont alors muettes pour elle (une nuit hors protocole n'a pas à respecter une fenêtre ni un intervalle), et elle ne compte pas comme passage 1 ou 2 dans le solde de saison : elle y figure à part, en « hors protocole ». La qualité est orthogonale au statut d'avancement : une nuit opportuniste s'importe, se transforme, se vérifie et se dépose comme les autres. Elle se déclare de trois façons : à l'import, dans la modale du passage, ou dérivée automatiquement par R35.
- R35 : un carré d'un tiers est un carré que la synchronisation Vigie-Chiro rattache à un autre observateur que celui connecté. Ses nuits sont présumées opportunistes et marquées comme telles à chaque synchronisation. Le marquage dérivé est à sens unique : il ajoute, il ne retire jamais. Un carré transféré ne réécrit pas l'histoire (les nuits y ont bien été réalisées alors qu'il appartenait à un tiers), et surtout un retrait automatique effacerait les déclarations faites à la main pour des participations qui, elles, ne sont liées à aucun carré distant. Sans profil lisible côté plateforme, aucun carré n'est présumé d'un tiers.
- R25 : un n° de carré est unique par utilisateur : un même utilisateur ne peut pas déclarer deux fois le même carré (alerte bloquante à la création ou au renommage d'un site ; la vérification exclut le site courant, pour qu'un simple renommage ne se bloque pas lui-même).
Géographie des carrés et des points¶
- R26 : un point d'écoute appartient à un carré de 2 km de côté du carroyage national Vigie-Chiro (« carrenat »). Ses coordonnées GPS doivent tomber dans l'emprise de ce carré. À l'édition cartographique des positions, le marqueur est contraint (clampé) au bord de la maille : on ne peut pas glisser un point hors de son carré. L'emprise du carré est déduite du centroïde officiel de la maille (référentiel
carrenatembarqué, ≈ 137 000 mailles couvrant la France métropolitaine), avec un repli : si le carré est hors référentiel, l'emprise est reconstruite autour des points géolocalisés du site. - R26bis : sur une frontière, la règle R26 est satisfaite par plusieurs carrés à la fois, et le modèle ne tranche pas. Deux mailles voisines partagent le bord de leur emprise ; un point posé dessus tombe dans les deux, et quatre se rejoignent à un coin. Mesuré le 2026-08-27 contre la plateforme : au milieu d'un côté commun, les deux centres sont à 997,7 m du point, à égalité stricte, et 1 412 m pour les quatre d'un coin. Le carroyage ne stockant que des centres, sa représentation ne peut pas porter la convention d'intervalle semi-ouvert qui départagerait, et un décalage de 5 m suffit à faire basculer lequel une requête rend en premier. L'application en tire deux conséquences symétriques : elle propose les candidats sans en choisir un, et elle accepte celui que l'observateur a déclaré dès qu'il figure parmi eux. Lui seul sait où était son micro.
- R27 : un point dont les coordonnées GPS ne sont pas (encore) saisies est tout de même situé, au centre de son carré (position approchée, distinguée visuellement d'une position mesurée). Si plusieurs points d'un même carré sont sans GPS, ils sont répartis en éventail autour du centre pour ne pas se superposer. Un point n'est non plaçable que si son carré est hors référentiel et qu'aucun point du site n'est géolocalisé (centre inconnu).
Convention de nommage des fichiers¶
- R6 : tout enregistrement original doit être renommé selon le préfixe
CarXXXXXX-AAAA-PassN-YY-avant tout dépôt. Les tirets sont des « tirets du 6 » (-, U+002D HYPHEN-MINUS), pas des cadratins ni des demi-cadratins. À n'oublier sous aucun. - R7 : le suffixe original de l'enregistreur (
PaRecPR<sn>_<AAAAMMJJ>_<HHMMSS>.wav) est conservé tel quel après le préfixe. - R8 : toute séquence d'écoute reprend le nom de son enregistrement original source, avec l'horodatage décalé de
index × 5 s(chaque tranche porte l'heure réelle de son début) et un suffixe_000systématique entre le nom de base et l'extension. Les suffixes_001,_002, … ne numérotent pas les tranches : ils servent uniquement à départager une collision de noms entre deux originaux qui se chevauchent sur la grille de 5 s (le plus ancien garde_000, le suivant passe en_001).
Copie protégée¶
- R9 : à l'import, l'application ne modifie jamais les originaux sur la carte SD (lecture seule). C'est une contrainte explicite du protocole Vigie-Chiro pour éviter toute perte de données. Elle produit toujours les séquences d'écoute transformées dans son espace de travail ; copier les enregistrements bruts est en revanche une option désactivée par défaut (cf. R22 et ADR 0036). Quand cette conservation est active, chaque copie de brut est vérifiée bit-à-bit : l'empreinte SHA-256 de la destination est recalculée et comparée à celle de la source ; toute divergence est une erreur (copie non fidèle). Dans le mode par défaut (sans copie), l'application capture malgré tout l'empreinte SHA-256 de chaque original (preuve d'identité) sans en garder de copie.
Import : résilience et inspection¶
- R29 : l'import est résilient. Un enregistrement original source illisible ou de format invalide est rejeté individuellement et consigné dans un rapport d'import (importés / rejetés / fichiers non pertinents) sans interrompre le traitement des autres fichiers. Le rapport porte aussi ce que l'import a rencontré sans le rejeter : le doublon de nuit quand l'observateur a choisi d'importer une nuit déjà présente, et les anomalies relevées au journal du capteur (réveil non programmé, batterie faible) - elles n'expliquent pas toujours un problème, mais elles éclairent une nuit qui paraît incomplète. Sont rejetés notamment : un en-tête WAV illisible ou de format invalide, et une fréquence d'acquisition non divisible par 10 (non ralentissable ×10 proprement, cf. R31). Un brut nativement expansé ×10 par l'enregistreur n'est pas un motif de rejet : c'est le cas normal (R31). Le remplacement d'une session existante est en revanche atomique : si l'import échoue globalement (annulation, tous les WAV rejetés, erreur disque), la session précédente est restaurée - rien n'est perdu.
- R30 : à l'inspection d'un dossier (avant import), l'application signale sans bloquer trois situations, à charge de l'utilisateur de décider : un mélange (le dossier contient des fichiers de plusieurs enregistreurs), une incohérence (le journal du capteur - n° de série, nuit - contredit les WAV) et une nuit déjà importée (un passage existe déjà pour le même enregistreur et la même date). Aucune de ces alertes n'empêche de lancer l'import.
- R31 : l'import accepte les enregistrements bruts de l'enregistreur, y compris ceux que le Passive Recorder écrit déjà expansés ×10 - en-tête estampillé à
Fe/10(ex. 38 400 Hz pour une acquisition à 384 kHz), échantillons conservés. C'est le cas normal, pas un motif de rejet. L'application résout la vraie fréquence d'acquisitionFeavant de transformer : celle du journal s'il est présent ; sinon l'en-tête s'il est déjà une acquisition plausible (≥ 96 kHz, brut direct) ; sinon l'en-tête multiplié par 10 (repli sur le comportement natif du PR). C'est donc l'inverse d'un rejet : un en-tête « trop bas » est corrigé, pas refusé. Le seul rejet lié à la fréquence est une fréquence d'acquisition non divisible par 10 (non ralentissable ×10 proprement) : le fichier est alors rejeté individuellement (R29), sans interrompre l'import des autres.
Transformation¶
- R10 : la transformation d'un enregistrement original le découpe en tranches de 5 s réelles, puis ralentit ×10 chaque tranche (expansion de temps). Le découpage porte donc sur le signal brut, pas sur le signal déjà ralenti : une séquence d'écoute contient 5 s d'enregistrement et dure 50 s à l'écoute. Pour un enregistrement original de durée
D(en secondes réelles), on obtientceil(D / 5)séquences. La dernière séquence peut être plus courte que 5 s. Le découpage et l'expansion sont pilotés par la vraie fréquence d'acquisitionFe, résolue avant transformation (cf. R31) et non par l'en-tête WAV - un brut PR est nativement estampillé àFe/10. Seule une fréquence d'acquisition non divisible par 10 est rejetée. - R11 : la transformation est deterministe : relancer la transformation sur les mêmes enregistrements originaux produit les mêmes séquences d'écoute au bit près.
Vérification d'enregistrement¶
- R12 : une sélection d'écoute est constituée automatiquement à l'ouverture de la vue, avec la méthode
RéparTemporelpar défaut (séquences réparties uniformément sur la nuit). - R13 : le verdict de chaque fichier son écouté (
Bon/Mauvais/Inexploitable) est saisi par l'utilisateur ; le verdict final du passage (OK/Utilisable/Inexploitable, état initialNon vérifié) en est dérivé automatiquement mais reste surchargeable à la main. Aucun seuil obligatoire d'écoute : l'utilisateur écoute tout ou partie de la sélection et reste responsable. - R14 : un passage au verdict final
Inexploitablene peut pas être déposé (alerte bloquante). Pour déposer, il faut le requalifier (re-vérifier jusqu'à un verdict déposable) ; une fois déposé, le verdict est figé.
Préparation du dépôt¶
- R33 : préparer le dépôt s'appuie sur une checklist de cohérence vivante (chaque contrôle est affiché, même satisfait : ✓ / ⚠ / ✗). Un contrôle bloquant (✗) interdit la préparation tant qu'il n'est pas corrigé : verdict
Inexploitable(R14), transformation incomplète, préfixe de fichier non conforme (R6), journal du capteur absent. Les contrôles non bloquants (⚠) - par exemple un relevé climatique absent (R20) - sont signalés mais laissent préparer. Quand la préparation réussit, le passage passe au statutPrêt à déposer.
Validation taxonomique (SHOULD)¶
- R15 : une observation est qualifiée de validée quand l'observateur a saisi un
taxon observateurégal autaxon Tadarida. La probabilité observateur n'entre pas dans ce statut : un_Vuréel porte une confiance textuelle (« SUR ») que le parseur lit comme probabilité inconnue, et l'exiger ferait passer une observation pourtant validée pour « non revue ». La confiance de l'observateur se déclare séparément par la certitude (SUR/PROBABLE/POSSIBLE, cf. C13), indépendante du statut. - R16 : une observation est qualifiée de corrigée quand
taxon observateur ≠ taxon Tadarida. Cas particulier : une observation créée à la main (sanstaxon Tadarida, cf. C13) tombe mécaniquement dans « corrigée » dès qu'un taxon observateur y est saisi, alors qu'il n'y avait rien à corriger. Le statut dérivé (StatutObservation) ne distingue pas encore ce cas d'une vraie correction. - R17 : une observation non touchée par l'utilisateur conserve uniquement les colonnes
tadarida_*, et l'export_Vu.csvreprend ces valeurs (l'utilisateur conserve ainsi la classification automatique par défaut). - R18 : deux modes de validation coexistent au MVP (au choix de l'utilisateur) :
- Mode inventaire : dès qu'une espèce est validée avec confiance sur une nuit, on ne valide plus les autres détections de la même espèce sur la même nuit.
- Mode activité : toutes les observations doivent être passées en revue (utile pour les études d'activité quantitative).
- 🟠 SHOULD / variante future - Mode inventaire pondéré : variante du mode inventaire qui rouvre la validation pour toute nouvelle détection de l'espèce dont la probabilité Tadarida est supérieure à celle de l'observation déjà validée comme référence. Hybride entre inventaire (gain de temps) et activité (capter les signaux plus francs qui apparaissent en cours de nuit). Origine : suggestion de Samuel - « on pourrait imaginer un 3e mode qui ne valide que les détections dont la proba est supérieure à celle de l'observation validée, qui se rapproche de ce qu'on fait sur certains projets ».
-
R24 : chaque observation porte un mode de validation (
manuel|auto|null) qui trace comment sa valeur courante detaxon observateura été établie :manuel: l'utilisateur a explicitement saisi ou modifié le taxon observateur (validation classique en modeactivité, ou validation explicite en modeinventaire).auto: le taxon a été propagé automatiquement par le modeinventaire(cf. R18) sans intervention manuelle - la classification dérive d'une validation antérieure sur la même espèce de la même nuit.null: aucune validation n'a encore été effectuée (l'observation conserve uniquement les colonnestadarida_*, cf. R17).
Ce mode est tracé en BD et restituable dans l'export
_Vu.csv(colonne optionnelle, à activer selon attentes Vigie-Chiro). Sa principale utilité : permettre à un évaluateur scientifique de distinguer ce qui a été réellement vérifié à l'oreille de ce qui a été propagé sur confiance. -
R32 : pendant la validation, une observation peut être marquée « séquence de référence ». L'export de la bibliothèque de sons de référence est constitué exactement de ces observations-là : pour chacune, le taxon retenu est le taxon observateur s'il a été validé, sinon le taxon Tadarida. Les fichiers audio sont copiés à plat dans le dossier d'export, accompagnés d'un CSV récapitulatif (
bibliotheque-sons.csv) où le taxon est une colonne ; ils ne sont pas rangés dans des sous-dossiers par taxon.
Suppression de sites et de points¶
- R28 : un point d'écoute ou un site qui porte des passages ne peut pas être supprimé (garde-fou contre la perte de données rattachées). La suppression est bloquée tant qu'au moins un passage y est rattaché ; l'interface l'indique (action désactivée avec info-bulle explicative, ou message au clic). Pour supprimer, il faut d'abord retirer les passages concernés.
Données¶
- R19 : le journal du capteur est un journal circulaire sur l'enregistreur (place limitée). En cas de saturation de la SD, des entrées plus anciennes peuvent être effacées. L'application n'a pas à reconstituer les pertes - elle exploite ce qui est présent.
- R20 : le relevé climatique peut être absent (sonde défaillante ou non installée). Dans ce cas, l'onglet diagnostic du passage le signale clairement plutôt que de masquer la section.
Arborescence sur disque¶
- R21 : toutes les données et tous les paramètres de l'application vivent dans un unique dossier « workspace » sur le disque local de l'utilisateur. Ce workspace contient les sessions d'enregistrement, la base SQLite et tout fichier de réglages utilisateur. Aucune donnée n'est dispersée ailleurs.
- Défaut proposé à l'installation :
<Documents>/VigieChiro-Companion/(résolu par OS :~/Documents/VigieChiro-Companion/sous Linux/macOS,%USERPROFILE%\Documents\VigieChiro-Companion\sous Windows). - Configurable depuis les préférences (onglet « Emplacements ») : utile en particulier pour les gros volumes (Samuel : 24 enregistreurs × 40-50 nuits → To cumulés), qui demanderont à pointer un disque externe. Le changement est pris en compte au prochain démarrage et ne déplace pas les données déjà présentes.
- Défaut proposé à l'installation :
- R22 : une session d'enregistrement occupe un sous-dossier du workspace dont le nom est exactement le préfixe défini par R6 (
Car<carre>-<annee>-Pass<n>-<point>). Dans ce sous-dossier :- les enregistrements originaux, si l'utilisateur a demandé de les conserver, sont rangés dans
bruts/(cf. R7). Ce dossier est absent par défaut : l'application lit les WAV directement depuis la carte et n'en garde pas de copie, la conservation étant une option de ré-analyse (cf. ADR 0036) ; - les séquences d'écoute sont rangées dans
transformes/(cf. R8) ; - les archives ZIP de dépôt (
<préfixe>-N.zip), quand elles ont été générées, sont rangées dansdepot/; elles sont régénérables à l'identique et peuvent être supprimées une fois téléversées ; - le journal du capteur (
LogPR<n>.txt) est à la racine de la session d'enregistrement (cf. C9) ; - le relevé climatique (
PaRecPR<sn>_THLog.csv), si présent, est aussi à la racine de la session d'enregistrement (cf. C10, R20).
- les enregistrements originaux, si l'utilisateur a demandé de les conserver, sont rangés dans
- R23 : le fichier de résultats Tadarida (
*-observations.csvou*-observations_Vu.csv) est lu à l'emplacement choisi par l'utilisateur (ou rapatrié de la plateforme). L'application n'en fait pas de copie et ne le déplace pas dans la session : seul son chemin d'origine est mémorisé comme provenance (colonnefile_pathdes résultats d'identification). Il n'est donc pas rangé danstransformes/.
Arborescence type d'un workspace contenant deux sessions d'enregistrement (un passage 1 et un passage 2 sur le même point) :
<workspace>/ ← R21 : configurable, défaut <Documents>/VigieChiro-Companion/
├── Car040962-2026-Pass1-A1/ ← R22 : nom = préfixe R6
│ ├── bruts/ ← R22 : originaux, SEULEMENT si conservation demandée
│ │ ├── Car040962-2026-Pass1-A1-PaRecPR1925492_20260622_213045.wav
│ │ ├── Car040962-2026-Pass1-A1-PaRecPR1925492_20260622_213101.wav
│ │ └── ...
│ ├── transformes/ ← R22 : séquences d'écoute R8 (horodatage + _000)
│ │ ├── Car040962-2026-Pass1-A1-PaRecPR1925492_20260622_213045_000.wav
│ │ ├── Car040962-2026-Pass1-A1-PaRecPR1925492_20260622_213050_000.wav
│ │ ├── Car040962-2026-Pass1-A1-PaRecPR1925492_20260622_213055_000.wav
│ │ └── ...
│ ├── depot/ ← R22 : archives ZIP de dépôt (régénérables)
│ │ ├── Car040962-2026-Pass1-A1-1.zip
│ │ └── Car040962-2026-Pass1-A1-2.zip
│ ├── LogPR1925492.txt ← R22 : journal capteur à la racine
│ └── PaRecPR1925492_THLog.csv ← R22 : relevé climatique (optionnel)
├── Car040962-2026-Pass2-A1/
│ └── ... ← même structure que ci-dessus
└── vigiechiro.db ← R21 : BD SQLite + réglages à la racine