Titre Synomap – Loop Specification v1 – Bloc ABC (flux normal, seedtime-only) Version ID : Synomap_Loop_Spec_v1_ABC Date : 2025-11-16 Périmètre : flux normal (sans erreurs) pour un torrent géré par Synomap, entre les états A, B, C Hypothèse v1 : condition de seed basée uniquement sur le seeding time (ratio ignoré) 0. Objet et périmètre Ce document décrit la spécification fonctionnelle du Synomap Loop pour le cas “normal” d’un torrent géré, structuré autour de trois états : STATE_A_NEW_MAPPED STATE_B_MIRROR_CREATED_SAVE_ON_DATA STATE_C_OK_SYNO Ce document ne traite pas : des erreurs de mapping (mapping_ambiguous), des catégories inconnues, des miroirs manquants/détruits, des erreurs qB ou timeouts persistants, du rôle détaillé des fichiers .state au-delà de la trace. Ces points feront l’objet de documents ultérieurs (v2, v3, …) qui s’appuieront sur la présente spécification. 1. Hypothèses générales 1.1. Topologie des chemins Côté OMV (source torrents) : /data/torrents/completed/sonarr/... /data/torrents/completed/radarr/... Côté Synology (miroirs et arborescence de destination) : /syno/torrents/completed/{sonarr,radarr} /syno/Series/... /syno/Films/... 1.2. Mapping canonique mapping_entries.txt est la seule source de vérité indiquant, pour un torrent géré, la paire (SRC_ABS, DST_ABS). Pour ce document, on suppose qu’il existe au plus une entrée valide par torrent (pas de cas ambigu). 1.3. qBittorrent Chaque torrent géré possède une entrée unique dans qB (pas de “double torrent” sur les mêmes fichiers). Les infos qB utilisées ici : save_path, seeding_time (ou équivalent), tags (notamment SYNO, SYNO_OK). 1.4. Fichiers .state Les fichiers .state existent mais ne pilotent pas la logique A/B/C. Ils servent de trace / debug, et éventuellement de secours si mapping_entries.txt est altéré. La boucle ABC ne dépend que de : mapping_entries.txt, FS, qB. 2. Stratégie globale et ciblage de la boucle 2.1. Stratégie de chemin cible (save_path) Stratégie retenue : S2_SYNO_CENTRIC Objectif final : pour un torrent géré par Synomap, le save_path qB doit pointer sur un chemin Synology de miroir (et non plus sur /data/...). /data/torrents/completed/ sert de zone de transit / historique, pas de destination long terme. 2.2. Condition de seed – v1 On définit une fonction booléenne : SeedConditionPassed = F(seeding_time, ratio, config) Dans cette v1 : ratio est ignoré (par exemple config.ratio_threshold = -1), SeedConditionPassed dépend uniquement de seeding_time (atteinte d’un seuil métier à définir). Le design permet d’intégrer ultérieurement le ratio et des combinaisons (time & ratio), sans casser la logique ABC. 3. Invariants du bloc ABC 3.1. Invariants généraux INV-ABC1 : la stratégie cible est S2_SYNO_CENTRIC. INV-ABC2 : la condition de seed utilise uniquement le seeding time (ratio ignoré). INV-ABC3 : mapping_entries.txt est la référence unique des paires SRC/DST. INV-ABC4 : les fichiers .state ne sont pas utilisés pour décider A/B/C. INV-ABC5 : un torrent C est un point fixe : aucun appel qB/FS ne doit être fait en C. 3.2. Invariants qB INV-QB1 : par torrent et par run, une seule chaîne d’actions qB est autorisée. INV-QB2 : aucune transition d’état ne se fait sans confirmation qB : un setLocation doit être suivi d’une relecture du torrent, si save_path n’est pas conforme, l’état ne progresse pas. INV-QB3 : en cas d’erreur qB ou de timeout, la transition est annulée pour ce run ; l’état reste en A ou B. INV-QB4 : tags SYNO et SYNO_OK ne sont posés/changés que lorsque les conditions de leurs paliers respectifs sont vérifiées. 3.3. Invariants d’opportunisme Un run peut effectuer la séquence A→B→C pour un torrent donné si et seulement si : la création des miroirs Syno réussit, SeedConditionPassed = true, setLocation qB retourne OK, la relecture qB confirme le save_path Synology attendu. 4. Modèle d’état ABC 4.1. STATE_A_NEW_MAPPED Conditions d’observation (début de run) mapping présent dans mapping_entries.txt pour ce torrent, SRC_ABS existe sous /data/torrents/completed/, DST_ABS (miroir Syno) n’existe pas encore, qB save_path = /data/..., tag SYNO_OK absent. Interprétation fonctionnelle Torrent découvert / pris en compte par Synomap. Éligible à la première création de miroirs Synology. 4.2. STATE_B_MIRROR_CREATED_SAVE_ON_DATA Conditions d’observation (début de run) mapping présent, SRC_ABS existe sous /data/..., DST_ABS existe sous /syno/..., qB save_path = /data/..., tag SYNO_OK absent (mais SYNO peut être présent), SeedConditionPassed = true ou false. Interprétation fonctionnelle Les miroirs Synology ont été créés. qB n’a pas encore été migré vers Synology. L’état B est strictement transitoire : la stratégie S2_SYNO_CENTRIC impose que la cible soit C. 4.3. STATE_C_OK_SYNO Conditions d’observation (début de run) mapping présent, SRC_ABS existe sous /data/..., DST_ABS existe sous /syno/..., qB save_path = chemin Synology attendu (miroir), tag SYNO_OK présent, SeedConditionPassed = true. Interprétation fonctionnelle Torrent arrivé à la cible logique de Synomap. Point fixe : la boucle ne doit plus lancer d’action (qB ou FS) pour ce torrent. 5. Logique de boucle et transitions Principe général Pour chaque run, pour chaque torrent mappé : Observer (mapping, FS, qB, tags, seeding_time). Classer en A, B, C ou “hors ABC”. Appliquer au plus une séquence d’actions déterministe (ou aucune, si C). 5.1. Transitions depuis A État courant : STATE_A_NEW_MAPPED. Cas A1 – SeedConditionPassed = false Conditions : SRC OK, DST absent, save_path=/data, SeedConditionPassed = false. Actions : Tenter de créer les miroirs Synology (hardlinks) à partir de SRC. Si création OK → au prochain run, le torrent sera observé en B. Si création échoue → pas de progression (futur état d’erreur hors périmètre de ce doc). Cas A2 – SeedConditionPassed = true (mode opportuniste) Conditions : SRC OK, DST absent, save_path=/data, SeedConditionPassed = true. Actions : Créer les miroirs Synology (DST). Si création OK, un recalcul logique place le torrent en B. Depuis cet état B logique et SeedConditionPassed = true : lancer setLocation qB vers le chemin Synology cible, relire les propriétés du torrent, si save_path == Syno attendu : poser ou basculer le tag en SYNO_OK, considérer le torrent comme C dès la fin de ce run. sinon : ne pas passer en C, le torrent restera en B (migration non confirmée). 5.2. Transitions depuis B État courant : STATE_B_MIRROR_CREATED_SAVE_ON_DATA. Cas B1 – SeedConditionPassed = false Conditions : mapping OK, SRC OK, DST OK, save_path=/data, SeedConditionPassed = false. Actions : Poser ou maintenir le tag SYNO (marqueur “pris en charge par Synomap”). Ne pas appeler setLocation. Le torrent reste en B. Cas B2 – SeedConditionPassed = true Conditions : mapping OK, SRC OK, DST OK, save_path=/data, SeedConditionPassed = true. Actions : Lancer setLocation qB vers le chemin Synology cible. Relire le torrent : si save_path == Syno attendu : remplacer SYNO par SYNO_OK (ou équivalent), considérer le torrent en C. sinon : ne pas changer d’état métier, rester en B (migration non confirmée). 5.3. Transitions depuis C État courant : STATE_C_OK_SYNO. Cas C1 – Point fixe Conditions : mapping OK, SRC/DST OK, save_path = Synology, tag SYNO_OK, SeedConditionPassed = true. Actions : Aucune action qB, aucune action FS. Le torrent est immédiatement SKIP pour ce run. Si, à un run ultérieur, les conditions de C ne sont plus réunies (ex : miroirs supprimés, save_path repassé sur /data), le torrent ne sera plus classé en C ; il basculera dans des états “anormaux” décrits dans de futurs documents (v2, v3, …). 6. Rôle des tags Tag SYNO Utilisé en B pour marquer les torrents dont les miroirs Synology ont été créés. Posé à la première transition A→B réussie. Tag SYNO_OK Utilisé en C pour marquer les torrents : migrés vers Synology côté qB (save_path Syno conforme), avec SeedConditionPassed = true. Remplace SYNO lors du passage confirmé B→C. Le couple (SYNO, SYNO_OK) permet au checker futur d’identifier rapidement où en est chaque torrent dans la boucle ABC. 7. Limitations et extensions prévues Ce document ne couvre pas : les cas de mapping_ambiguous (plusieurs entrées pour un torrent), les unknown_category, les miroirs détruits ou partiellement présents (DST manquant), les torrents orphelins dans qB ou dans le FS, les timeouts qB répétés ou persistants, la prise en compte du ratio dans SeedConditionPassed. Les extensions prévues : v2 : gestion des erreurs de mapping / catégories (états E, F, K). v3 : gestion des incohérences FS (miroirs cassés, SRC/DST manquants) – états G, H, I. v4 : gestion fine des mismatches qB (save_path, tags) – état D + modes de recovery. v5 : intégration du ratio dans la condition de seed, avec combinatoires configurables. Fin du document Synomap_Loop_Spec_v1_ABC_seedtime_only