plan
de95607 parent: 2442175 added
specs/003-config-contexte-travail/contracts/cli-config.md +69 -0 | new file mode 100644 | ||
| @@ -0,0 +1,69 @@ | ||
| 1 | +# Contrat CLI : `regine config` | |
| 2 | + | |
| 3 | +Façade CLI de ce module (cf. Principe CLI-first). Protocole texte : arguments en entrée, résultat sur stdout, erreurs sur stderr, code de sortie non-zéro en cas d'échec — aucun format binaire ni interactif requis pour ce contrat (une confirmation interactive reste possible pour les cas décrits ci-dessous, mais chaque commande DOIT rester scriptable via des flags explicites). | |
| 4 | + | |
| 5 | +## `regine config set-paths` | |
| 6 | + | |
| 7 | +Configure ou modifie un ou plusieurs des trois emplacements de travail (FR-001, FR-002, FR-010). | |
| 8 | + | |
| 9 | +**Entrée** : | |
| 10 | +``` | |
| 11 | +regine config set-paths [--temp-dir CHEMIN] [--local-work-dir CHEMIN] [--archive-smb PARTAGE_SMB] | |
| 12 | +``` | |
| 13 | + | |
| 14 | +**Sorties** : | |
| 15 | +- Succès : récapitulatif du contexte de travail enregistré sur stdout, code de sortie `0`. | |
| 16 | +- Répertoire manquant (FR-003) : proposition de création sur stdout ; sans confirmation (`--yes` ou prompt interactif), la commande s'arrête sans écrire, code de sortie non-zéro. | |
| 17 | +- Collision `temp-dir` == `local-work-dir` (Edge Case) : avertissement sur stderr ; nécessite `--force` pour confirmer explicitement, sinon code de sortie non-zéro. | |
| 18 | +- `archive-smb` invalide (pas un partage réseau, Edge Case) : erreur sur stderr, code de sortie non-zéro, rien n'est enregistré. | |
| 19 | +- Changement de `--local-work-dir` alors qu'un travail non réconcilié existe sous l'ancien chemin (FR-010, Clarification n°1) : erreur sur stderr listant le(s) dossier(s) à réconcilier/archiver, code de sortie non-zéro, rien n'est modifié. | |
| 20 | + | |
| 21 | +## `regine config show` | |
| 22 | + | |
| 23 | +Affiche le contexte de travail actif, y compris l'état de disponibilité connu du partage SMB. | |
| 24 | + | |
| 25 | +**Entrée** : | |
| 26 | +``` | |
| 27 | +regine config show [--json] | |
| 28 | +``` | |
| 29 | + | |
| 30 | +**Sorties** : | |
| 31 | +- Contexte non configuré (Edge Case) : message clair sur stdout listant les chemins manquants, code de sortie non-zéro. | |
| 32 | +- Contexte configuré : chemins actifs + état SMB (`mounted` / `unavailable` / `unknown`) sur stdout (texte ou JSON selon `--json`), code de sortie `0`. | |
| 33 | + | |
| 34 | +## `regine config cameras list` | |
| 35 | + | |
| 36 | +Liste les boîtiers connus dans la base de contexte centralisée (FR-008, User Story 3). | |
| 37 | + | |
| 38 | +**Entrée** : | |
| 39 | +``` | |
| 40 | +regine config cameras list [--json] | |
| 41 | +``` | |
| 42 | + | |
| 43 | +**Sorties** : tableau (modèle, numéro de série le cas échéant, nom lisible ou `(non nommé)`, source `import`/`parcours_nas`) sur stdout, code `0`. Liste vide (aucun import effectué) : message explicite, pas une erreur. | |
| 44 | + | |
| 45 | +## `regine config cameras rename` | |
| 46 | + | |
| 47 | +Attribue un nom lisible à un boîtier détecté (FR-008/FR-009). | |
| 48 | + | |
| 49 | +**Entrée** : | |
| 50 | +``` | |
| 51 | +regine config cameras rename --id ID --nom "Nom lisible" | |
| 52 | +``` | |
| 53 | + | |
| 54 | +**Sorties** : | |
| 55 | +- Succès : confirmation sur stdout, code `0`. Le nom devient immédiatement actif pour la désambiguïsation (FR-009). | |
| 56 | +- `ID` inconnu : erreur sur stderr, code non-zéro. | |
| 57 | + | |
| 58 | +## `regine config cameras scan-nas` | |
| 59 | + | |
| 60 | +Déclenche volontairement le parcours complet de l'archive NAS pour détecter des boîtiers non encore connus (FR-012, optionnel). | |
| 61 | + | |
| 62 | +**Entrée** : | |
| 63 | +``` | |
| 64 | +regine config cameras scan-nas [--confirm] | |
| 65 | +``` | |
| 66 | + | |
| 67 | +**Sorties** : | |
| 68 | +- Sans `--confirm` : avertissement sur stdout indiquant que l'opération peut être longue sur une grosse archive, et invite à relancer avec `--confirm` ; code de sortie non-zéro (rien n'est exécuté), cohérent avec le caractère volontaire de FR-012. | |
| 69 | +- Avec `--confirm` : parcours exécuté, nouveaux boîtiers ajoutés avec `source=parcours_nas`, récapitulatif sur stdout, code `0`. Nécessite que l'archive NAS soit accessible (sinon comportement de User Story 2 : détection d'indisponibilité + assistance au montage). | |
| new file mode 100644 | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | +# Contrat CLI : `regine config` | ||
| 2 | + | ||
| 3 | +Façade CLI de ce module (cf. Principe CLI-first). Protocole texte : arguments en entrée, résultat sur stdout, erreurs sur stderr, code de sortie non-zéro en cas d'échec — aucun format binaire ni interactif requis pour ce contrat (une confirmation interactive reste possible pour les cas décrits ci-dessous, mais chaque commande DOIT rester scriptable via des flags explicites). | ||
| 4 | + | ||
| 5 | +## `regine config set-paths` | ||
| 6 | + | ||
| 7 | +Configure ou modifie un ou plusieurs des trois emplacements de travail (FR-001, FR-002, FR-010). | ||
| 8 | + | ||
| 9 | +**Entrée** : | ||
| 10 | +``` | ||
| 11 | +regine config set-paths [--temp-dir CHEMIN] [--local-work-dir CHEMIN] [--archive-smb PARTAGE_SMB] | ||
| 12 | +``` | ||
| 13 | + | ||
| 14 | +**Sorties** : | ||
| 15 | +- Succès : récapitulatif du contexte de travail enregistré sur stdout, code de sortie `0`. | ||
| 16 | +- Répertoire manquant (FR-003) : proposition de création sur stdout ; sans confirmation (`--yes` ou prompt interactif), la commande s'arrête sans écrire, code de sortie non-zéro. | ||
| 17 | +- Collision `temp-dir` == `local-work-dir` (Edge Case) : avertissement sur stderr ; nécessite `--force` pour confirmer explicitement, sinon code de sortie non-zéro. | ||
| 18 | +- `archive-smb` invalide (pas un partage réseau, Edge Case) : erreur sur stderr, code de sortie non-zéro, rien n'est enregistré. | ||
| 19 | +- Changement de `--local-work-dir` alors qu'un travail non réconcilié existe sous l'ancien chemin (FR-010, Clarification n°1) : erreur sur stderr listant le(s) dossier(s) à réconcilier/archiver, code de sortie non-zéro, rien n'est modifié. | ||
| 20 | + | ||
| 21 | +## `regine config show` | ||
| 22 | + | ||
| 23 | +Affiche le contexte de travail actif, y compris l'état de disponibilité connu du partage SMB. | ||
| 24 | + | ||
| 25 | +**Entrée** : | ||
| 26 | +``` | ||
| 27 | +regine config show [--json] | ||
| 28 | +``` | ||
| 29 | + | ||
| 30 | +**Sorties** : | ||
| 31 | +- Contexte non configuré (Edge Case) : message clair sur stdout listant les chemins manquants, code de sortie non-zéro. | ||
| 32 | +- Contexte configuré : chemins actifs + état SMB (`mounted` / `unavailable` / `unknown`) sur stdout (texte ou JSON selon `--json`), code de sortie `0`. | ||
| 33 | + | ||
| 34 | +## `regine config cameras list` | ||
| 35 | + | ||
| 36 | +Liste les boîtiers connus dans la base de contexte centralisée (FR-008, User Story 3). | ||
| 37 | + | ||
| 38 | +**Entrée** : | ||
| 39 | +``` | ||
| 40 | +regine config cameras list [--json] | ||
| 41 | +``` | ||
| 42 | + | ||
| 43 | +**Sorties** : tableau (modèle, numéro de série le cas échéant, nom lisible ou `(non nommé)`, source `import`/`parcours_nas`) sur stdout, code `0`. Liste vide (aucun import effectué) : message explicite, pas une erreur. | ||
| 44 | + | ||
| 45 | +## `regine config cameras rename` | ||
| 46 | + | ||
| 47 | +Attribue un nom lisible à un boîtier détecté (FR-008/FR-009). | ||
| 48 | + | ||
| 49 | +**Entrée** : | ||
| 50 | +``` | ||
| 51 | +regine config cameras rename --id ID --nom "Nom lisible" | ||
| 52 | +``` | ||
| 53 | + | ||
| 54 | +**Sorties** : | ||
| 55 | +- Succès : confirmation sur stdout, code `0`. Le nom devient immédiatement actif pour la désambiguïsation (FR-009). | ||
| 56 | +- `ID` inconnu : erreur sur stderr, code non-zéro. | ||
| 57 | + | ||
| 58 | +## `regine config cameras scan-nas` | ||
| 59 | + | ||
| 60 | +Déclenche volontairement le parcours complet de l'archive NAS pour détecter des boîtiers non encore connus (FR-012, optionnel). | ||
| 61 | + | ||
| 62 | +**Entrée** : | ||
| 63 | +``` | ||
| 64 | +regine config cameras scan-nas [--confirm] | ||
| 65 | +``` | ||
| 66 | + | ||
| 67 | +**Sorties** : | ||
| 68 | +- Sans `--confirm` : avertissement sur stdout indiquant que l'opération peut être longue sur une grosse archive, et invite à relancer avec `--confirm` ; code de sortie non-zéro (rien n'est exécuté), cohérent avec le caractère volontaire de FR-012. | ||
| 69 | +- Avec `--confirm` : parcours exécuté, nouveaux boîtiers ajoutés avec `source=parcours_nas`, récapitulatif sur stdout, code `0`. Nécessite que l'archive NAS soit accessible (sinon comportement de User Story 2 : détection d'indisponibilité + assistance au montage). | ||
added
specs/003-config-contexte-travail/data-model.md +73 -0 | new file mode 100644 | ||
| @@ -0,0 +1,73 @@ | ||
| 1 | +# Data Model: Configuration du contexte de travail de Régine | |
| 2 | + | |
| 3 | +Entités dérivées de `spec.md` § Key Entities et Functional Requirements. | |
| 4 | + | |
| 5 | +## Contexte de travail | |
| 6 | + | |
| 7 | +Représente l'état de configuration actif d'une installation de Régine. Unique par installation (cf. Assumptions). | |
| 8 | + | |
| 9 | +| Champ | Type | Règles | | |
| 10 | +|---|---|---| | |
| 11 | +| `temp_dir` | chemin absolu | Doit exister ou être proposé à la création (FR-003) ; DOIT être différent de `local_work_dir` (Edge Case, avertissement sinon) | | |
| 12 | +| `local_work_dir` | chemin absolu | Doit exister ou être proposé à la création (FR-003) ; changement refusé si un travail non réconcilié y est présent (FR-010, cf. état ci-dessous) | | |
| 13 | +| `archive_smb_path` | chemin réseau (partage SMB) | DOIT correspondre à un partage réseau, pas à un dossier local (Edge Case) | | |
| 14 | +| `smb_last_known_state` | énumération : `mounted` \| `unavailable` \| `unknown` | Alimenté par la vérification de disponibilité avant chaque opération (FR-004/FR-005) | | |
| 15 | + | |
| 16 | +**Règle d'état** : `local_work_dir` ne peut être modifié que si aucun checkout ni import n'y est en cours de réconciliation/archivage (cf. Clarification 2026-09-18 n°1, FR-010, Acceptance Scenario 5 de User Story 1). Cette vérification interroge la ou les bases de données de travail par dossier présentes sous `local_work_dir`. | |
| 17 | + | |
| 18 | +## Base de données de travail (par dossier) | |
| 19 | + | |
| 20 | +Une base SQLite par dossier local, à sa racine (FR-006), archivée avec lui vers le NAS (FR-007). Le schéma détaillé (tables de manifeste, hash, identifiants pérennes) relève du module `archive`/`dossier` (constitution § Workflow d'archivage, section 12 des notes de conception) ; ce plan couvre uniquement son **initialisation** : | |
| 21 | + | |
| 22 | +| Élément | Description | | |
| 23 | +|---|---| | |
| 24 | +| Emplacement | Racine du dossier local concerné, sous `local_work_dir` | | |
| 25 | +| Convention de format | `PRAGMA user_version` (numéro de schéma), `PRAGMA application_id` (identifiant Régine) — cf. constitution § Workflow d'archivage | | |
| 26 | +| Cycle de vie | Créée à l'initialisation du dossier local ; déplacée/archivée avec le dossier lors du réarchivage vers le NAS ; sa présence sous un dossier non réconcilié est ce qui bloque un changement de `local_work_dir` (règle ci-dessus) | | |
| 27 | + | |
| 28 | +## Base de contexte centralisée | |
| 29 | + | |
| 30 | +Base SQLite unique au niveau du contexte de travail (pas par dossier), distincte de la base de données de travail par dossier (Assumptions). | |
| 31 | + | |
| 32 | +**Table `boitiers`** | |
| 33 | + | |
| 34 | +| Champ | Type | Règles | | |
| 35 | +|---|---|---| | |
| 36 | +| `id` | identifiant interne | Clé primaire | | |
| 37 | +| `modele` | texte | Tag EXIF `Model`, enregistré à chaque import (FR-008) | | |
| 38 | +| `numero_serie` | texte, nullable | Tag EXIF `BodySerialNumber`, quand présent et exploitable (cf. `specs/002-profil-boitiers-optionnel`) | | |
| 39 | +| `nom_lisible` | texte, nullable | Attribué par l'utilisateur (FR-008/FR-009) ; `NULL` tant que non nommé | | |
| 40 | +| `premiere_rencontre` | horodatage | Date du premier import ayant révélé ce boîtier | | |
| 41 | +| `source` | énumération : `import` \| `parcours_nas` | Distingue une entrée alimentée automatiquement à l'import (FR-008) d'une entrée trouvée par le parcours volontaire du NAS (FR-012) | | |
| 42 | + | |
| 43 | +**Règle d'unicité** : unique sur (`modele`, `numero_serie`) quand `numero_serie` est exploitable ; sinon unique sur `modele` seul, jusqu'à ce qu'une collision réelle (détectée par le module import, cf. `specs/002-profil-boitiers-optionnel`) force la création d'une entrée distincte. | |
| 44 | + | |
| 45 | +**Relation** : `nom_lisible`, une fois défini, DOIT être réutilisé par tout module identifiant ce même boîtier par la suite (FR-009) — relation de référence, pas de duplication de la donnée. | |
| 46 | + | |
| 47 | +## Boîtier nommé | |
| 48 | + | |
| 49 | +Vue logique sur une ligne de la table `boitiers` dont `nom_lisible` n'est pas `NULL`. Pas une entité de stockage séparée — introduite dans `spec.md` pour la lisibilité côté utilisateur. | |
| 50 | + | |
| 51 | +## État / transitions | |
| 52 | + | |
| 53 | +```text | |
| 54 | +[Répertoire de travail local] | |
| 55 | + │ | |
| 56 | + │ configuré (FR-001) | |
| 57 | + ▼ | |
| 58 | + ┌───────────┐ travail non réconcilié présent ┌──────────────────────┐ | |
| 59 | + │ Libre │ ───────────────────────────────────▶│ Occupé (bloquant) │ | |
| 60 | + │ (modifiable)│ │ (changement refusé, │ | |
| 61 | + └───────────┘ ◀─────────────────────────────────── │ FR-010) │ | |
| 62 | + ▲ réconciliation / archivage └──────────────────────┘ | |
| 63 | + │ du dossier concerné | |
| 64 | + │ changement de chemin autorisé | |
| 65 | +``` | |
| 66 | + | |
| 67 | +```text | |
| 68 | +[Boîtier] | |
| 69 | + Détecté (source=import, nom_lisible=NULL) | |
| 70 | + │ utilisateur attribue un nom (FR-008/009) | |
| 71 | + ▼ | |
| 72 | + Nommé (nom_lisible défini) | |
| 73 | +``` | |
| new file mode 100644 | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | +# Data Model: Configuration du contexte de travail de Régine | ||
| 2 | + | ||
| 3 | +Entités dérivées de `spec.md` § Key Entities et Functional Requirements. | ||
| 4 | + | ||
| 5 | +## Contexte de travail | ||
| 6 | + | ||
| 7 | +Représente l'état de configuration actif d'une installation de Régine. Unique par installation (cf. Assumptions). | ||
| 8 | + | ||
| 9 | +| Champ | Type | Règles | | ||
| 10 | +|---|---|---| | ||
| 11 | +| `temp_dir` | chemin absolu | Doit exister ou être proposé à la création (FR-003) ; DOIT être différent de `local_work_dir` (Edge Case, avertissement sinon) | | ||
| 12 | +| `local_work_dir` | chemin absolu | Doit exister ou être proposé à la création (FR-003) ; changement refusé si un travail non réconcilié y est présent (FR-010, cf. état ci-dessous) | | ||
| 13 | +| `archive_smb_path` | chemin réseau (partage SMB) | DOIT correspondre à un partage réseau, pas à un dossier local (Edge Case) | | ||
| 14 | +| `smb_last_known_state` | énumération : `mounted` \| `unavailable` \| `unknown` | Alimenté par la vérification de disponibilité avant chaque opération (FR-004/FR-005) | | ||
| 15 | + | ||
| 16 | +**Règle d'état** : `local_work_dir` ne peut être modifié que si aucun checkout ni import n'y est en cours de réconciliation/archivage (cf. Clarification 2026-09-18 n°1, FR-010, Acceptance Scenario 5 de User Story 1). Cette vérification interroge la ou les bases de données de travail par dossier présentes sous `local_work_dir`. | ||
| 17 | + | ||
| 18 | +## Base de données de travail (par dossier) | ||
| 19 | + | ||
| 20 | +Une base SQLite par dossier local, à sa racine (FR-006), archivée avec lui vers le NAS (FR-007). Le schéma détaillé (tables de manifeste, hash, identifiants pérennes) relève du module `archive`/`dossier` (constitution § Workflow d'archivage, section 12 des notes de conception) ; ce plan couvre uniquement son **initialisation** : | ||
| 21 | + | ||
| 22 | +| Élément | Description | | ||
| 23 | +|---|---| | ||
| 24 | +| Emplacement | Racine du dossier local concerné, sous `local_work_dir` | | ||
| 25 | +| Convention de format | `PRAGMA user_version` (numéro de schéma), `PRAGMA application_id` (identifiant Régine) — cf. constitution § Workflow d'archivage | | ||
| 26 | +| Cycle de vie | Créée à l'initialisation du dossier local ; déplacée/archivée avec le dossier lors du réarchivage vers le NAS ; sa présence sous un dossier non réconcilié est ce qui bloque un changement de `local_work_dir` (règle ci-dessus) | | ||
| 27 | + | ||
| 28 | +## Base de contexte centralisée | ||
| 29 | + | ||
| 30 | +Base SQLite unique au niveau du contexte de travail (pas par dossier), distincte de la base de données de travail par dossier (Assumptions). | ||
| 31 | + | ||
| 32 | +**Table `boitiers`** | ||
| 33 | + | ||
| 34 | +| Champ | Type | Règles | | ||
| 35 | +|---|---|---| | ||
| 36 | +| `id` | identifiant interne | Clé primaire | | ||
| 37 | +| `modele` | texte | Tag EXIF `Model`, enregistré à chaque import (FR-008) | | ||
| 38 | +| `numero_serie` | texte, nullable | Tag EXIF `BodySerialNumber`, quand présent et exploitable (cf. `specs/002-profil-boitiers-optionnel`) | | ||
| 39 | +| `nom_lisible` | texte, nullable | Attribué par l'utilisateur (FR-008/FR-009) ; `NULL` tant que non nommé | | ||
| 40 | +| `premiere_rencontre` | horodatage | Date du premier import ayant révélé ce boîtier | | ||
| 41 | +| `source` | énumération : `import` \| `parcours_nas` | Distingue une entrée alimentée automatiquement à l'import (FR-008) d'une entrée trouvée par le parcours volontaire du NAS (FR-012) | | ||
| 42 | + | ||
| 43 | +**Règle d'unicité** : unique sur (`modele`, `numero_serie`) quand `numero_serie` est exploitable ; sinon unique sur `modele` seul, jusqu'à ce qu'une collision réelle (détectée par le module import, cf. `specs/002-profil-boitiers-optionnel`) force la création d'une entrée distincte. | ||
| 44 | + | ||
| 45 | +**Relation** : `nom_lisible`, une fois défini, DOIT être réutilisé par tout module identifiant ce même boîtier par la suite (FR-009) — relation de référence, pas de duplication de la donnée. | ||
| 46 | + | ||
| 47 | +## Boîtier nommé | ||
| 48 | + | ||
| 49 | +Vue logique sur une ligne de la table `boitiers` dont `nom_lisible` n'est pas `NULL`. Pas une entité de stockage séparée — introduite dans `spec.md` pour la lisibilité côté utilisateur. | ||
| 50 | + | ||
| 51 | +## État / transitions | ||
| 52 | + | ||
| 53 | +```text | ||
| 54 | +[Répertoire de travail local] | ||
| 55 | + │ | ||
| 56 | + │ configuré (FR-001) | ||
| 57 | + ▼ | ||
| 58 | + ┌───────────┐ travail non réconcilié présent ┌──────────────────────┐ | ||
| 59 | + │ Libre │ ───────────────────────────────────▶│ Occupé (bloquant) │ | ||
| 60 | + │ (modifiable)│ │ (changement refusé, │ | ||
| 61 | + └───────────┘ ◀─────────────────────────────────── │ FR-010) │ | ||
| 62 | + ▲ réconciliation / archivage └──────────────────────┘ | ||
| 63 | + │ du dossier concerné | ||
| 64 | + │ changement de chemin autorisé | ||
| 65 | +``` | ||
| 66 | + | ||
| 67 | +```text | ||
| 68 | +[Boîtier] | ||
| 69 | + Détecté (source=import, nom_lisible=NULL) | ||
| 70 | + │ utilisateur attribue un nom (FR-008/009) | ||
| 71 | + ▼ | ||
| 72 | + Nommé (nom_lisible défini) | ||
| 73 | +``` | ||
added
specs/003-config-contexte-travail/plan.md +110 -0 | new file mode 100644 | ||
| @@ -0,0 +1,110 @@ | ||
| 1 | +# Implementation Plan: Configuration du contexte de travail de Régine | |
| 2 | + | |
| 3 | +**Branch**: `003-config-contexte-travail` | **Date**: 2026-09-18 | **Spec**: [spec.md](./spec.md) | |
| 4 | + | |
| 5 | +**Input**: Feature specification from `/specs/003-config-contexte-travail/spec.md` | |
| 6 | + | |
| 7 | +## Summary | |
| 8 | + | |
| 9 | +Le module de configuration établit le contexte de travail dont dépendent tous les autres modules de Régine : trois emplacements (répertoire temporaire, répertoire de travail local, archive NAS/SMB), l'initialisation d'une base de données de travail à la racine du répertoire de travail local (archivée avec chaque dossier), une base de contexte centralisée alimentée à chaque import avec les références de boîtiers rencontrés (permettant de leur attribuer un nom lisible sans réimport ni parcours du NAS), et une assistance au montage natif du partage SMB quand il est indisponible. Approche technique : un module Python (`config`) dans le paquet `regine-core` d'un monorepo à quatre parties (bibliothèque centrale `regine-core`, façades `regine-cli`, `regine-gui`, `regine-agent`), exposé dans un premier temps via `regine-cli` (cf. Principe CLI-first et Principe VI de la constitution), stockant son état dans SQLite selon les mêmes conventions que le manifeste persistant par dossier déjà retenu (`PRAGMA user_version`/`application_id`). | |
| 10 | + | |
| 11 | +## Technical Context | |
| 12 | + | |
| 13 | +**Language/Version**: Python 3.11+ (langage retenu pour la bibliothèque centrale de Régine, cf. `docs/interface-cli-gui-architecture.md`) | |
| 14 | + | |
| 15 | +**Primary Dependencies**: bibliothèque standard uniquement pour ce module (`sqlite3`, `pathlib`, `shutil`, `subprocess` pour déclencher le montage natif) ; pas de dépendance tierce nouvelle identifiée (cf. research.md) | |
| 16 | + | |
| 17 | +**Storage**: SQLite — deux bases distinctes : la base de contexte centralisée (niveau contexte de travail, ce module) et les bases de données de travail par dossier (une par dossier local, initialisées par ce module mais dont le schéma détaillé relève du module `archive`/`dossier`, cf. constitution § Workflow d'archivage) | |
| 18 | + | |
| 19 | +**Testing**: pytest ; tests de contrat sur la surface CLI (entrées/sorties texte, codes de sortie), tests d'intégration sur le cycle configuration → initialisation de la base de travail, tests unitaires sur la validation des chemins et la logique de désambiguïsation de boîtiers | |
| 20 | + | |
| 21 | +**Target Platform**: Poste de travail de bureau (macOS en priorité pour cette itération ; Windows/Linux non couverts par ce plan, cf. research.md) — l'abstraction de déclenchement du montage SMB isole ce choix pour ne pas bloquer une extension future | |
| 22 | + | |
| 23 | +**Project Type**: Monorepo — une bibliothèque centrale (`regine-core`) et trois façades indépendantes et installables séparément (`regine-cli`, `regine-gui`, `regine-agent`), conformément au Principe VI de la constitution. Ce plan implémente `regine-core` (module `config`) et `regine-cli` ; `regine-gui` et `regine-agent` sont réservés dans la structure du dépôt mais ne sont pas construits par ce plan (cf. Structure Decision et research.md § 5). | |
| 24 | + | |
| 25 | +**Performance Goals**: Pas de cible chiffrée spécifique ; la détection de boîtiers (FR-008/SC-007) doit rester quasi instantanée car elle ne lit que la base de contexte locale, sans parcours réseau par défaut | |
| 26 | + | |
| 27 | +**Constraints**: aucune gestion ni stockage d'identifiants réseau par Régine (FR-004, authentification déléguée à l'OS) ; exécution sans démon, un processus par lancement (contrainte technique de la constitution) ; refus (pas de migration silencieuse) du changement de répertoire de travail local tant qu'un travail n'est pas réconcilié/archivé (FR-010) | |
| 28 | + | |
| 29 | +**Scale/Scope**: usage mono-utilisateur, mono-poste ; un seul contexte de travail actif par installation (cf. Assumptions de la spec) | |
| 30 | + | |
| 31 | +## Constitution Check | |
| 32 | + | |
| 33 | +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* | |
| 34 | + | |
| 35 | +| Principe / contrainte | Évaluation | Justification | | |
| 36 | +|---|---|---| | |
| 37 | +| I. Fichier maître intouchable | N/A | Ce module ne lit ni ne modifie de fichier maître ; il ne fait que stocker des chemins et des références de boîtiers. | | |
| 38 | +| II. Confirmation explicite avant toute action à risque | PASS | Aucune écriture sur l'archive n'est effectuée par ce module (FR-003 propose la création de répertoires locaux, non destructif ; FR-010 refuse plutôt que d'exécuter une migration silencieuse). Les actions à risque restent celles des modules import/archive, déjà couvertes par leurs specs respectives. | | |
| 39 | +| III. Identité par contenu, jamais par nom de fichier seul | N/A | Hors périmètre : ce module ne détecte ni renommage ni doublon de fichier. | | |
| 40 | +| IV. Métadonnées ouvertes et embarquées | PASS | Le nom lisible d'un boîtier (FR-009) est une convenance locale d'affichage, pas une métadonnée descriptive/de droits au sens du Principe IV (légende, mots-clés, personnes, crédit, copyright, licence) ; l'identité du boîtier reste fondée sur les tags EXIF déjà embarqués par l'appareil (modèle, numéro de série), lesquels restent la source de vérité portable. | | |
| 41 | +| V. L'utilisateur décide, Régine suggère | PASS | FR-003 (création de répertoire) et FR-012 (parcours NAS) restent des propositions/actions volontaires, jamais automatiques. | | |
| 42 | +| VI. Bibliothèque centrale, façades minces | PASS | Le monorepo matérialise physiquement la séparation : `regine-core` porte toute la logique métier (module `config`), `regine-cli` ne fait qu'appeler `regine-core` et formatter le résultat. `regine-gui`/`regine-agent` sont réservés dans la structure pour dépendre de `regine-core` de la même façon le moment venu, sans logique dupliquée. | | |
| 43 | +| CLI-first | PASS | Toute capacité de ce module est exposée en CLI avant toute GUI. | | |
| 44 | +| Exécution sans démon | PASS | Chaque commande CLI est un processus isolé ; le déclenchement du montage SMB est une action ponctuelle, pas un service en arrière-plan. | | |
| 45 | +| Formats ouverts et documentés | PASS | SQLite, déjà retenu par la constitution pour le manifeste persistant, réutilisé ici avec les mêmes conventions (`PRAGMA user_version`/`application_id`). | | |
| 46 | + | |
| 47 | +Aucune violation identifiée ; la section Complexity Tracking reste vide. | |
| 48 | + | |
| 49 | +**Re-check post Phase 1** (après génération de `data-model.md`, `contracts/cli-config.md`, `quickstart.md`) : le modèle de données (deux bases SQLite distinctes, conventions `PRAGMA user_version`/`application_id` réutilisées) et le contrat CLI (protocole texte in/out, refus explicite plutôt que migration silencieuse pour FR-010, parcours NAS non exécuté sans `--confirm` pour FR-012) confirment chaque évaluation PASS ci-dessus. Aucune violation nouvelle introduite par la conception détaillée. | |
| 50 | + | |
| 51 | +## Project Structure | |
| 52 | + | |
| 53 | +### Documentation (this feature) | |
| 54 | + | |
| 55 | +```text | |
| 56 | +specs/003-config-contexte-travail/ | |
| 57 | +├── plan.md # This file (/speckit-plan command output) | |
| 58 | +├── research.md # Phase 0 output (/speckit-plan command) | |
| 59 | +├── data-model.md # Phase 1 output (/speckit-plan command) | |
| 60 | +├── quickstart.md # Phase 1 output (/speckit-plan command) | |
| 61 | +├── contracts/ # Phase 1 output (/speckit-plan command) | |
| 62 | +│ └── cli-config.md | |
| 63 | +└── tasks.md # Phase 2 output (/speckit-tasks command - NOT created by /speckit-plan) | |
| 64 | +``` | |
| 65 | + | |
| 66 | +### Source Code (repository root) — monorepo à 4 parties | |
| 67 | + | |
| 68 | +```text | |
| 69 | +packages/ | |
| 70 | +├── regine-core/ # Bibliothèque centrale — toute la logique métier | |
| 71 | +│ ├── pyproject.toml | |
| 72 | +│ ├── src/ | |
| 73 | +│ │ └── regine_core/ | |
| 74 | +│ │ ├── __init__.py | |
| 75 | +│ │ └── config/ | |
| 76 | +│ │ ├── __init__.py | |
| 77 | +│ │ ├── context.py # Contexte de travail : lecture/écriture des 3 chemins, validation | |
| 78 | +│ │ ├── db.py # Ouverture/initialisation SQLite (base de contexte centralisée + base de travail par dossier) | |
| 79 | +│ │ ├── smb.py # Détection de disponibilité + déclenchement du montage natif SMB (research.md) | |
| 80 | +│ │ └── cameras.py # Enregistrement/désambiguïsation/nommage des boîtiers | |
| 81 | +│ └── tests/ | |
| 82 | +│ ├── contract/ # Contrats internes de regine_core (objets structurés retournés, cf. Principe VI) | |
| 83 | +│ ├── integration/ | |
| 84 | +│ │ └── test_config_context.py # Cycle configuration → initialisation base de travail → changement de chemin bloqué | |
| 85 | +│ └── unit/ | |
| 86 | +│ ├── test_context_paths.py # Validation/création des répertoires, cas de collision | |
| 87 | +│ └── test_cameras_db.py # Désambiguïsation modèle/numéro de série, nommage | |
| 88 | +│ | |
| 89 | +├── regine-cli/ # Façade CLI — dépend de regine-core, aucune logique métier propre | |
| 90 | +│ ├── pyproject.toml | |
| 91 | +│ ├── src/ | |
| 92 | +│ │ └── regine_cli/ | |
| 93 | +│ │ ├── __init__.py | |
| 94 | +│ │ └── config_cmd.py # Sous-commandes `regine config ...` (cf. contracts/cli-config.md) | |
| 95 | +│ └── tests/ | |
| 96 | +│ └── contract/ | |
| 97 | +│ └── test_cli_config.py # Contrat de la surface CLI (entrées/sorties texte, codes de sortie) | |
| 98 | +│ | |
| 99 | +├── regine-gui/ # Façade GUI — réservée, non implémentée par ce plan | |
| 100 | +│ └── (scaffold vide : pyproject.toml déclarant la dépendance à regine-core, aucun code métier) | |
| 101 | +│ | |
| 102 | +└── regine-agent/ # Façade agent IA — réservée, non implémentée par ce plan | |
| 103 | + └── (scaffold vide : pyproject.toml déclarant la dépendance à regine-core, aucun code métier) | |
| 104 | +``` | |
| 105 | + | |
| 106 | +**Structure Decision**: Monorepo à quatre parties (Option 1 adaptée du template, multi-packages plutôt que `src/` unique), conformément au Principe VI de la constitution (bibliothèque centrale, façades minces) et à la demande explicite d'organiser dès maintenant la place de la GUI et de l'agent IA. `regine-core` est le premier package de la bibliothèque centrale de Régine (aucun code existant avant ce plan) et pose la convention `packages/<nom>/src/<nom_paquet>/` que les modules métier futurs (`import`, `archive`, `dossier`, `metadata`, `integrity`, `camera_profile` de specs/002) réutiliseront à l'intérieur de `regine-core`. Ce plan implémente `regine-core/config` et `regine-cli` ; `regine-gui` et `regine-agent` sont créés comme paquets vides (dépendance déclarée vers `regine-core`, sans code métier) pour réserver la structure, sans être développés ici — leur implémentation relèvera de specs dédiées. L'outillage de workspace (gestion des dépendances inter-paquets, lockfile commun) est tranché en research.md § 5. | |
| 107 | + | |
| 108 | +## Complexity Tracking | |
| 109 | + | |
| 110 | +*Aucune violation de gate à justifier — section laissée vide intentionnellement.* | |
| new file mode 100644 | |||
| @@ -0,0 +1,110 @@ | |||
| 1 | +# Implementation Plan: Configuration du contexte de travail de Régine | ||
| 2 | + | ||
| 3 | +**Branch**: `003-config-contexte-travail` | **Date**: 2026-09-18 | **Spec**: [spec.md](./spec.md) | ||
| 4 | + | ||
| 5 | +**Input**: Feature specification from `/specs/003-config-contexte-travail/spec.md` | ||
| 6 | + | ||
| 7 | +## Summary | ||
| 8 | + | ||
| 9 | +Le module de configuration établit le contexte de travail dont dépendent tous les autres modules de Régine : trois emplacements (répertoire temporaire, répertoire de travail local, archive NAS/SMB), l'initialisation d'une base de données de travail à la racine du répertoire de travail local (archivée avec chaque dossier), une base de contexte centralisée alimentée à chaque import avec les références de boîtiers rencontrés (permettant de leur attribuer un nom lisible sans réimport ni parcours du NAS), et une assistance au montage natif du partage SMB quand il est indisponible. Approche technique : un module Python (`config`) dans le paquet `regine-core` d'un monorepo à quatre parties (bibliothèque centrale `regine-core`, façades `regine-cli`, `regine-gui`, `regine-agent`), exposé dans un premier temps via `regine-cli` (cf. Principe CLI-first et Principe VI de la constitution), stockant son état dans SQLite selon les mêmes conventions que le manifeste persistant par dossier déjà retenu (`PRAGMA user_version`/`application_id`). | ||
| 10 | + | ||
| 11 | +## Technical Context | ||
| 12 | + | ||
| 13 | +**Language/Version**: Python 3.11+ (langage retenu pour la bibliothèque centrale de Régine, cf. `docs/interface-cli-gui-architecture.md`) | ||
| 14 | + | ||
| 15 | +**Primary Dependencies**: bibliothèque standard uniquement pour ce module (`sqlite3`, `pathlib`, `shutil`, `subprocess` pour déclencher le montage natif) ; pas de dépendance tierce nouvelle identifiée (cf. research.md) | ||
| 16 | + | ||
| 17 | +**Storage**: SQLite — deux bases distinctes : la base de contexte centralisée (niveau contexte de travail, ce module) et les bases de données de travail par dossier (une par dossier local, initialisées par ce module mais dont le schéma détaillé relève du module `archive`/`dossier`, cf. constitution § Workflow d'archivage) | ||
| 18 | + | ||
| 19 | +**Testing**: pytest ; tests de contrat sur la surface CLI (entrées/sorties texte, codes de sortie), tests d'intégration sur le cycle configuration → initialisation de la base de travail, tests unitaires sur la validation des chemins et la logique de désambiguïsation de boîtiers | ||
| 20 | + | ||
| 21 | +**Target Platform**: Poste de travail de bureau (macOS en priorité pour cette itération ; Windows/Linux non couverts par ce plan, cf. research.md) — l'abstraction de déclenchement du montage SMB isole ce choix pour ne pas bloquer une extension future | ||
| 22 | + | ||
| 23 | +**Project Type**: Monorepo — une bibliothèque centrale (`regine-core`) et trois façades indépendantes et installables séparément (`regine-cli`, `regine-gui`, `regine-agent`), conformément au Principe VI de la constitution. Ce plan implémente `regine-core` (module `config`) et `regine-cli` ; `regine-gui` et `regine-agent` sont réservés dans la structure du dépôt mais ne sont pas construits par ce plan (cf. Structure Decision et research.md § 5). | ||
| 24 | + | ||
| 25 | +**Performance Goals**: Pas de cible chiffrée spécifique ; la détection de boîtiers (FR-008/SC-007) doit rester quasi instantanée car elle ne lit que la base de contexte locale, sans parcours réseau par défaut | ||
| 26 | + | ||
| 27 | +**Constraints**: aucune gestion ni stockage d'identifiants réseau par Régine (FR-004, authentification déléguée à l'OS) ; exécution sans démon, un processus par lancement (contrainte technique de la constitution) ; refus (pas de migration silencieuse) du changement de répertoire de travail local tant qu'un travail n'est pas réconcilié/archivé (FR-010) | ||
| 28 | + | ||
| 29 | +**Scale/Scope**: usage mono-utilisateur, mono-poste ; un seul contexte de travail actif par installation (cf. Assumptions de la spec) | ||
| 30 | + | ||
| 31 | +## Constitution Check | ||
| 32 | + | ||
| 33 | +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* | ||
| 34 | + | ||
| 35 | +| Principe / contrainte | Évaluation | Justification | | ||
| 36 | +|---|---|---| | ||
| 37 | +| I. Fichier maître intouchable | N/A | Ce module ne lit ni ne modifie de fichier maître ; il ne fait que stocker des chemins et des références de boîtiers. | | ||
| 38 | +| II. Confirmation explicite avant toute action à risque | PASS | Aucune écriture sur l'archive n'est effectuée par ce module (FR-003 propose la création de répertoires locaux, non destructif ; FR-010 refuse plutôt que d'exécuter une migration silencieuse). Les actions à risque restent celles des modules import/archive, déjà couvertes par leurs specs respectives. | | ||
| 39 | +| III. Identité par contenu, jamais par nom de fichier seul | N/A | Hors périmètre : ce module ne détecte ni renommage ni doublon de fichier. | | ||
| 40 | +| IV. Métadonnées ouvertes et embarquées | PASS | Le nom lisible d'un boîtier (FR-009) est une convenance locale d'affichage, pas une métadonnée descriptive/de droits au sens du Principe IV (légende, mots-clés, personnes, crédit, copyright, licence) ; l'identité du boîtier reste fondée sur les tags EXIF déjà embarqués par l'appareil (modèle, numéro de série), lesquels restent la source de vérité portable. | | ||
| 41 | +| V. L'utilisateur décide, Régine suggère | PASS | FR-003 (création de répertoire) et FR-012 (parcours NAS) restent des propositions/actions volontaires, jamais automatiques. | | ||
| 42 | +| VI. Bibliothèque centrale, façades minces | PASS | Le monorepo matérialise physiquement la séparation : `regine-core` porte toute la logique métier (module `config`), `regine-cli` ne fait qu'appeler `regine-core` et formatter le résultat. `regine-gui`/`regine-agent` sont réservés dans la structure pour dépendre de `regine-core` de la même façon le moment venu, sans logique dupliquée. | | ||
| 43 | +| CLI-first | PASS | Toute capacité de ce module est exposée en CLI avant toute GUI. | | ||
| 44 | +| Exécution sans démon | PASS | Chaque commande CLI est un processus isolé ; le déclenchement du montage SMB est une action ponctuelle, pas un service en arrière-plan. | | ||
| 45 | +| Formats ouverts et documentés | PASS | SQLite, déjà retenu par la constitution pour le manifeste persistant, réutilisé ici avec les mêmes conventions (`PRAGMA user_version`/`application_id`). | | ||
| 46 | + | ||
| 47 | +Aucune violation identifiée ; la section Complexity Tracking reste vide. | ||
| 48 | + | ||
| 49 | +**Re-check post Phase 1** (après génération de `data-model.md`, `contracts/cli-config.md`, `quickstart.md`) : le modèle de données (deux bases SQLite distinctes, conventions `PRAGMA user_version`/`application_id` réutilisées) et le contrat CLI (protocole texte in/out, refus explicite plutôt que migration silencieuse pour FR-010, parcours NAS non exécuté sans `--confirm` pour FR-012) confirment chaque évaluation PASS ci-dessus. Aucune violation nouvelle introduite par la conception détaillée. | ||
| 50 | + | ||
| 51 | +## Project Structure | ||
| 52 | + | ||
| 53 | +### Documentation (this feature) | ||
| 54 | + | ||
| 55 | +```text | ||
| 56 | +specs/003-config-contexte-travail/ | ||
| 57 | +├── plan.md # This file (/speckit-plan command output) | ||
| 58 | +├── research.md # Phase 0 output (/speckit-plan command) | ||
| 59 | +├── data-model.md # Phase 1 output (/speckit-plan command) | ||
| 60 | +├── quickstart.md # Phase 1 output (/speckit-plan command) | ||
| 61 | +├── contracts/ # Phase 1 output (/speckit-plan command) | ||
| 62 | +│ └── cli-config.md | ||
| 63 | +└── tasks.md # Phase 2 output (/speckit-tasks command - NOT created by /speckit-plan) | ||
| 64 | +``` | ||
| 65 | + | ||
| 66 | +### Source Code (repository root) — monorepo à 4 parties | ||
| 67 | + | ||
| 68 | +```text | ||
| 69 | +packages/ | ||
| 70 | +├── regine-core/ # Bibliothèque centrale — toute la logique métier | ||
| 71 | +│ ├── pyproject.toml | ||
| 72 | +│ ├── src/ | ||
| 73 | +│ │ └── regine_core/ | ||
| 74 | +│ │ ├── __init__.py | ||
| 75 | +│ │ └── config/ | ||
| 76 | +│ │ ├── __init__.py | ||
| 77 | +│ │ ├── context.py # Contexte de travail : lecture/écriture des 3 chemins, validation | ||
| 78 | +│ │ ├── db.py # Ouverture/initialisation SQLite (base de contexte centralisée + base de travail par dossier) | ||
| 79 | +│ │ ├── smb.py # Détection de disponibilité + déclenchement du montage natif SMB (research.md) | ||
| 80 | +│ │ └── cameras.py # Enregistrement/désambiguïsation/nommage des boîtiers | ||
| 81 | +│ └── tests/ | ||
| 82 | +│ ├── contract/ # Contrats internes de regine_core (objets structurés retournés, cf. Principe VI) | ||
| 83 | +│ ├── integration/ | ||
| 84 | +│ │ └── test_config_context.py # Cycle configuration → initialisation base de travail → changement de chemin bloqué | ||
| 85 | +│ └── unit/ | ||
| 86 | +│ ├── test_context_paths.py # Validation/création des répertoires, cas de collision | ||
| 87 | +│ └── test_cameras_db.py # Désambiguïsation modèle/numéro de série, nommage | ||
| 88 | +│ | ||
| 89 | +├── regine-cli/ # Façade CLI — dépend de regine-core, aucune logique métier propre | ||
| 90 | +│ ├── pyproject.toml | ||
| 91 | +│ ├── src/ | ||
| 92 | +│ │ └── regine_cli/ | ||
| 93 | +│ │ ├── __init__.py | ||
| 94 | +│ │ └── config_cmd.py # Sous-commandes `regine config ...` (cf. contracts/cli-config.md) | ||
| 95 | +│ └── tests/ | ||
| 96 | +│ └── contract/ | ||
| 97 | +│ └── test_cli_config.py # Contrat de la surface CLI (entrées/sorties texte, codes de sortie) | ||
| 98 | +│ | ||
| 99 | +├── regine-gui/ # Façade GUI — réservée, non implémentée par ce plan | ||
| 100 | +│ └── (scaffold vide : pyproject.toml déclarant la dépendance à regine-core, aucun code métier) | ||
| 101 | +│ | ||
| 102 | +└── regine-agent/ # Façade agent IA — réservée, non implémentée par ce plan | ||
| 103 | + └── (scaffold vide : pyproject.toml déclarant la dépendance à regine-core, aucun code métier) | ||
| 104 | +``` | ||
| 105 | + | ||
| 106 | +**Structure Decision**: Monorepo à quatre parties (Option 1 adaptée du template, multi-packages plutôt que `src/` unique), conformément au Principe VI de la constitution (bibliothèque centrale, façades minces) et à la demande explicite d'organiser dès maintenant la place de la GUI et de l'agent IA. `regine-core` est le premier package de la bibliothèque centrale de Régine (aucun code existant avant ce plan) et pose la convention `packages/<nom>/src/<nom_paquet>/` que les modules métier futurs (`import`, `archive`, `dossier`, `metadata`, `integrity`, `camera_profile` de specs/002) réutiliseront à l'intérieur de `regine-core`. Ce plan implémente `regine-core/config` et `regine-cli` ; `regine-gui` et `regine-agent` sont créés comme paquets vides (dépendance déclarée vers `regine-core`, sans code métier) pour réserver la structure, sans être développés ici — leur implémentation relèvera de specs dédiées. L'outillage de workspace (gestion des dépendances inter-paquets, lockfile commun) est tranché en research.md § 5. | ||
| 107 | + | ||
| 108 | +## Complexity Tracking | ||
| 109 | + | ||
| 110 | +*Aucune violation de gate à justifier — section laissée vide intentionnellement.* | ||
added
specs/003-config-contexte-travail/quickstart.md +71 -0 | new file mode 100644 | ||
| @@ -0,0 +1,71 @@ | ||
| 1 | +# Quickstart : validation du module de configuration | |
| 2 | + | |
| 3 | +Ce guide valide de bout en bout les trois user stories de `spec.md` via la surface CLI décrite dans `contracts/cli-config.md`. À exécuter une fois le module implémenté (cf. `tasks.md`). | |
| 4 | + | |
| 5 | +## Prérequis | |
| 6 | + | |
| 7 | +- Installation locale de Régine avec le module `config` implémenté (`src/regine/config/`, `src/regine/cli/config_cmd.py`). | |
| 8 | +- Un répertoire temporaire et un répertoire de travail local vides, sur disque local. | |
| 9 | +- Un partage SMB accessible (réel ou simulé) pour les scénarios 2 et 5 ; un partage volontairement démonté pour le scénario 4. | |
| 10 | + | |
| 11 | +## Scénario 1 — Configuration initiale (User Story 1, P1) | |
| 12 | + | |
| 13 | +```bash | |
| 14 | +regine config set-paths \ | |
| 15 | + --temp-dir ~/regine/tmp \ | |
| 16 | + --local-work-dir ~/regine/travail \ | |
| 17 | + --archive-smb smb://nas.local/regine-archive | |
| 18 | +``` | |
| 19 | + | |
| 20 | +**Résultat attendu** : si `~/regine/tmp` ou `~/regine/travail` n'existent pas, Régine propose de les créer (accepter) ; le contexte est enregistré (`regine config show` affiche les trois chemins), et `~/regine/travail` contient une base de données de travail initialisée (FR-006, SC-003). | |
| 21 | + | |
| 22 | +## Scénario 2 — Modification d'un chemin sans travail en cours (User Story 1, Acceptance Scenario 4) | |
| 23 | + | |
| 24 | +```bash | |
| 25 | +regine config set-paths --temp-dir ~/regine/tmp2 | |
| 26 | +``` | |
| 27 | + | |
| 28 | +**Résultat attendu** : le changement est appliqué sans erreur ; `regine config show` reflète le nouveau chemin ; les boîtiers déjà nommés (scénario 6) restent inchangés (SC-005). | |
| 29 | + | |
| 30 | +## Scénario 3 — Changement de répertoire de travail bloqué par un travail non réconcilié (Clarification n°1, FR-010, SC-006) | |
| 31 | + | |
| 32 | +```bash | |
| 33 | +# Simuler un import/checkout en cours sous ~/regine/travail (non réconcilié), puis : | |
| 34 | +regine config set-paths --local-work-dir ~/regine/autre-travail | |
| 35 | +``` | |
| 36 | + | |
| 37 | +**Résultat attendu** : la commande échoue (code de sortie non-zéro) et indique précisément le(s) dossier(s) à réconcilier ou archiver avant de pouvoir changer de chemin — rien n'est déplacé ni perdu. | |
| 38 | + | |
| 39 | +## Scénario 4 — Assistance au montage SMB indisponible (User Story 2, P2) | |
| 40 | + | |
| 41 | +```bash | |
| 42 | +# Démonter/débrancher le partage SMB configuré, puis déclencher une opération qui en a besoin : | |
| 43 | +regine config show | |
| 44 | +``` | |
| 45 | + | |
| 46 | +**Résultat attendu** : Régine détecte l'indisponibilité, déclenche le mécanisme de montage natif de l'OS (SC-002), puis, une fois le montage rétabli manuellement par l'utilisateur, une nouvelle invocation de la commande aboutit sans reconfiguration. | |
| 47 | + | |
| 48 | +## Scénario 5 — Nommer un boîtier à partir d'un import déjà effectué (User Story 3, P3) | |
| 49 | + | |
| 50 | +```bash | |
| 51 | +# Après au moins un import ayant enregistré un boîtier (cf. specs/001-import-photos) : | |
| 52 | +regine config cameras list | |
| 53 | +regine config cameras rename --id 1 --nom "Fuji principal" | |
| 54 | +regine config cameras list | |
| 55 | +``` | |
| 56 | + | |
| 57 | +**Résultat attendu** : le boîtier apparaît d'abord comme `(non nommé)`, puis porte le nom `Fuji principal` après renommage, sans qu'aucun nouvel import ni parcours du NAS n'ait été nécessaire (SC-004, SC-007). | |
| 58 | + | |
| 59 | +## Scénario 6 — Parcours volontaire du NAS pour un dossier archivé avant cette fonctionnalité (FR-012) | |
| 60 | + | |
| 61 | +```bash | |
| 62 | +regine config cameras scan-nas | |
| 63 | +# Puis, après confirmation : | |
| 64 | +regine config cameras scan-nas --confirm | |
| 65 | +``` | |
| 66 | + | |
| 67 | +**Résultat attendu** : la première invocation avertit du coût potentiel et n'exécute rien (code non-zéro) ; la seconde, avec `--confirm`, parcourt l'archive et ajoute les boîtiers trouvés avec la source `parcours_nas`. | |
| 68 | + | |
| 69 | +## Critères de sortie | |
| 70 | + | |
| 71 | +Les six scénarios ci-dessus, exécutés dans l'ordre sur un contexte propre, doivent tous produire le résultat attendu sans intervention manuelle sur la base de données (uniquement via la CLI). Tout écart doit être tracé comme régression avant de considérer la fonctionnalité prête pour `/speckit-tasks` → implémentation suivante. | |
| new file mode 100644 | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | +# Quickstart : validation du module de configuration | ||
| 2 | + | ||
| 3 | +Ce guide valide de bout en bout les trois user stories de `spec.md` via la surface CLI décrite dans `contracts/cli-config.md`. À exécuter une fois le module implémenté (cf. `tasks.md`). | ||
| 4 | + | ||
| 5 | +## Prérequis | ||
| 6 | + | ||
| 7 | +- Installation locale de Régine avec le module `config` implémenté (`src/regine/config/`, `src/regine/cli/config_cmd.py`). | ||
| 8 | +- Un répertoire temporaire et un répertoire de travail local vides, sur disque local. | ||
| 9 | +- Un partage SMB accessible (réel ou simulé) pour les scénarios 2 et 5 ; un partage volontairement démonté pour le scénario 4. | ||
| 10 | + | ||
| 11 | +## Scénario 1 — Configuration initiale (User Story 1, P1) | ||
| 12 | + | ||
| 13 | +```bash | ||
| 14 | +regine config set-paths \ | ||
| 15 | + --temp-dir ~/regine/tmp \ | ||
| 16 | + --local-work-dir ~/regine/travail \ | ||
| 17 | + --archive-smb smb://nas.local/regine-archive | ||
| 18 | +``` | ||
| 19 | + | ||
| 20 | +**Résultat attendu** : si `~/regine/tmp` ou `~/regine/travail` n'existent pas, Régine propose de les créer (accepter) ; le contexte est enregistré (`regine config show` affiche les trois chemins), et `~/regine/travail` contient une base de données de travail initialisée (FR-006, SC-003). | ||
| 21 | + | ||
| 22 | +## Scénario 2 — Modification d'un chemin sans travail en cours (User Story 1, Acceptance Scenario 4) | ||
| 23 | + | ||
| 24 | +```bash | ||
| 25 | +regine config set-paths --temp-dir ~/regine/tmp2 | ||
| 26 | +``` | ||
| 27 | + | ||
| 28 | +**Résultat attendu** : le changement est appliqué sans erreur ; `regine config show` reflète le nouveau chemin ; les boîtiers déjà nommés (scénario 6) restent inchangés (SC-005). | ||
| 29 | + | ||
| 30 | +## Scénario 3 — Changement de répertoire de travail bloqué par un travail non réconcilié (Clarification n°1, FR-010, SC-006) | ||
| 31 | + | ||
| 32 | +```bash | ||
| 33 | +# Simuler un import/checkout en cours sous ~/regine/travail (non réconcilié), puis : | ||
| 34 | +regine config set-paths --local-work-dir ~/regine/autre-travail | ||
| 35 | +``` | ||
| 36 | + | ||
| 37 | +**Résultat attendu** : la commande échoue (code de sortie non-zéro) et indique précisément le(s) dossier(s) à réconcilier ou archiver avant de pouvoir changer de chemin — rien n'est déplacé ni perdu. | ||
| 38 | + | ||
| 39 | +## Scénario 4 — Assistance au montage SMB indisponible (User Story 2, P2) | ||
| 40 | + | ||
| 41 | +```bash | ||
| 42 | +# Démonter/débrancher le partage SMB configuré, puis déclencher une opération qui en a besoin : | ||
| 43 | +regine config show | ||
| 44 | +``` | ||
| 45 | + | ||
| 46 | +**Résultat attendu** : Régine détecte l'indisponibilité, déclenche le mécanisme de montage natif de l'OS (SC-002), puis, une fois le montage rétabli manuellement par l'utilisateur, une nouvelle invocation de la commande aboutit sans reconfiguration. | ||
| 47 | + | ||
| 48 | +## Scénario 5 — Nommer un boîtier à partir d'un import déjà effectué (User Story 3, P3) | ||
| 49 | + | ||
| 50 | +```bash | ||
| 51 | +# Après au moins un import ayant enregistré un boîtier (cf. specs/001-import-photos) : | ||
| 52 | +regine config cameras list | ||
| 53 | +regine config cameras rename --id 1 --nom "Fuji principal" | ||
| 54 | +regine config cameras list | ||
| 55 | +``` | ||
| 56 | + | ||
| 57 | +**Résultat attendu** : le boîtier apparaît d'abord comme `(non nommé)`, puis porte le nom `Fuji principal` après renommage, sans qu'aucun nouvel import ni parcours du NAS n'ait été nécessaire (SC-004, SC-007). | ||
| 58 | + | ||
| 59 | +## Scénario 6 — Parcours volontaire du NAS pour un dossier archivé avant cette fonctionnalité (FR-012) | ||
| 60 | + | ||
| 61 | +```bash | ||
| 62 | +regine config cameras scan-nas | ||
| 63 | +# Puis, après confirmation : | ||
| 64 | +regine config cameras scan-nas --confirm | ||
| 65 | +``` | ||
| 66 | + | ||
| 67 | +**Résultat attendu** : la première invocation avertit du coût potentiel et n'exécute rien (code non-zéro) ; la seconde, avec `--confirm`, parcourt l'archive et ajoute les boîtiers trouvés avec la source `parcours_nas`. | ||
| 68 | + | ||
| 69 | +## Critères de sortie | ||
| 70 | + | ||
| 71 | +Les six scénarios ci-dessus, exécutés dans l'ordre sur un contexte propre, doivent tous produire le résultat attendu sans intervention manuelle sur la base de données (uniquement via la CLI). Tout écart doit être tracé comme régression avant de considérer la fonctionnalité prête pour `/speckit-tasks` → implémentation suivante. | ||
added
specs/003-config-contexte-travail/research.md +54 -0 | new file mode 100644 | ||
| @@ -0,0 +1,54 @@ | ||
| 1 | +# Research: Configuration du contexte de travail de Régine | |
| 2 | + | |
| 3 | +## 1. Plateforme cible et déclenchement du montage natif SMB | |
| 4 | + | |
| 5 | +**Decision**: Prioriser macOS pour cette itération. Le déclenchement du montage se fait via `open smb://<hôte>/<partage>` (ouvre le mécanisme natif de montage de Finder, avec authentification gérée entièrement par l'OS) ; la détection de disponibilité consiste à vérifier l'accessibilité du point de montage local avant chaque opération nécessitant l'archive. Le mécanisme est isolé derrière une interface (`src/regine/config/smb.py`) pour permettre d'ajouter Windows (`net use` / explorateur) et Linux (`gio mount smb://...`) plus tard sans toucher au reste du module. | |
| 6 | + | |
| 7 | +**Rationale**: Le poste de développement et d'usage actuel du projet est macOS ; Windows/Linux ne sont mentionnés dans les notes de conception que comme options futures pour la GUI (PySide6 vs web), jamais comme cible immédiate. Isoler le mécanisme derrière une interface respecte le Principe VI de la constitution (bibliothèque centrale, façades minces) et le principe de simplicité déjà appliqué ailleurs dans le projet (pas de mécanisme pour des cas hypothétiques non encore demandés). | |
| 8 | + | |
| 9 | +**Alternatives considered**: | |
| 10 | +- Gérer soi-même le montage SMB multiplateforme via une bibliothèque tierce (`pysmb`, `smbprotocol`) — rejeté : la clarification du 2026-09-18 sur cette spec exclut explicitement que Régine gère ou stocke des identifiants réseau ; cette responsabilité reste déléguée à l'OS. | |
| 11 | +- Implémenter les trois OS dès cette itération — rejeté pour limiter la portée initiale ; l'abstraction retenue permet de le faire plus tard sans re-conception. | |
| 12 | + | |
| 13 | +## 2. Schéma de la base de contexte centralisée (SQLite) | |
| 14 | + | |
| 15 | +**Decision**: Réutiliser les conventions déjà actées par la constitution pour le manifeste persistant par dossier (§ Workflow d'archivage, section 12 des notes de conception) : un fichier SQLite unique, `PRAGMA user_version` pour le numéro de schéma, `PRAGMA application_id` pour marquer le format Régine, écriture transactionnelle. Table principale `boitiers` : identifiant interne, modèle EXIF, numéro de série EXIF (nullable), nom lisible (nullable), horodatage de première rencontre. Unicité sur (modèle, numéro de série) quand le numéro de série est exploitable, sinon sur le modèle seul tant qu'aucune collision réelle ne force une distinction plus fine (cohérent avec `specs/002-profil-boitiers-optionnel`). | |
| 16 | + | |
| 17 | +**Rationale**: Cohérence avec le mécanisme déjà retenu pour les bases par dossier (mêmes garanties transactionnelles, même stratégie de version de format) plutôt que d'inventer un second mécanisme de persistance pour un besoin très proche ; SQLite est explicitement le format recommandé par la constitution pour l'archivage long terme. | |
| 18 | + | |
| 19 | +**Alternatives considered**: | |
| 20 | +- Fichier JSON pour la base de contexte — rejeté : pas d'écriture transactionnelle, risque de corruption en cas de coupure, alors que c'est précisément ce que le choix SQLite du projet cherche à éviter ailleurs. | |
| 21 | +- Une table dans la même base SQLite qu'un manifeste de dossier — rejeté : la base de contexte centralisée n'est pas liée à un dossier particulier et ne doit pas être archivée avec lui (cf. Assumptions de la spec). | |
| 22 | + | |
| 23 | +## 3. Validation des répertoires (existence, écriture, espace disque) | |
| 24 | + | |
| 25 | +**Decision**: Utiliser les primitives standard de Python (`pathlib.Path.exists`/`mkdir`, `os.access`, `shutil.disk_usage`) pour vérifier l'existence, la capacité d'écriture et l'espace disponible avant toute opération de configuration ou d'initialisation de la base de données de travail. | |
| 26 | + | |
| 27 | +**Rationale**: Ces vérifications sont simples et entièrement couvertes par la bibliothèque standard ; le projet préfère des dépendances minimales (cf. Principe VI, pas de complexité non justifiée). | |
| 28 | + | |
| 29 | +**Alternatives considered**: | |
| 30 | +- Bibliothèque tierce de gestion de systèmes de fichiers multiplateforme — rejeté, complexité non justifiée pour un besoin déjà couvert nativement. | |
| 31 | + | |
| 32 | +## 4. Convention de surface CLI | |
| 33 | + | |
| 34 | +**Decision**: Sous-commandes `regine config set-paths`, `regine config show`, `regine config cameras list`, `regine config cameras rename`, suivant les conventions CLI Unix standard déjà actées par la constitution (arguments/flags en entrée, texte sur stdout, erreurs sur stderr, code de sortie non-zéro en cas d'échec). | |
| 35 | + | |
| 36 | +**Rationale**: Cohérence avec la contrainte technique CLI-first déjà actée (protocole texte in/out) ; pas de nouvelle convention à inventer. | |
| 37 | + | |
| 38 | +**Alternatives considered**: | |
| 39 | +- Fichier de configuration statique édité à la main (YAML/TOML), sans commande dédiée — rejeté : contredit FR-003 (proposer de créer les répertoires), FR-004/FR-005 (détection et mémorisation dynamiques du montage SMB) et FR-010 (refus actif d'un changement tant qu'un travail n'est pas réconcilié), qui impliquent une logique active plutôt qu'un simple fichier statique. | |
| 40 | + | |
| 41 | +## 5. Organisation monorepo (bibliothèque centrale + 3 façades) | |
| 42 | + | |
| 43 | +**Decision**: Adopter un monorepo à quatre paquets Python indépendants et installables séparément : `regine-core` (bibliothèque centrale, toute la logique métier), `regine-cli`, `regine-gui`, `regine-agent` (façades, chacune dépendant de `regine-core` sans logique métier propre). Outillage de workspace : `uv` (gestion de dépendances et lockfile unique au niveau du dépôt, `uv.lock`), avec un `pyproject.toml` par paquet sous `packages/<nom>/` suivant le format standard PEP 621. `regine-gui` et `regine-agent` sont créés comme paquets vides (dépendance déclarée, aucun code métier) pour réserver la structure dès cette itération, sans être implémentés maintenant. | |
| 44 | + | |
| 45 | +**Rationale**: La demande explicite est de penser dès maintenant la place des 4 parties techniques (lib, CLI, GUI, agent IA) plutôt que de les découvrir au fur et à mesure. Un monorepo à paquets séparés rend le Principe VI (bibliothèque centrale, façades minces) vérifiable structurellement : une façade qui importerait autre chose que l'API publique de `regine-core` serait une violation visible dès la déclaration des dépendances du paquet, pas seulement une convention à surveiller par relecture. `uv` est l'outil de gestion de paquets/workspace Python le plus rapide et le plus simple à opérer à la date de ce plan, avec un support natif des workspaces multi-paquets et un lockfile unique — cohérent avec la préférence du projet pour des dépendances minimales et une exécution sans démon (pas de service d'outillage à faire tourner, juste un binaire). | |
| 46 | + | |
| 47 | +**Alternatives considered**: | |
| 48 | +- Un seul paquet `src/regine/` avec des sous-modules `cli/`, `gui/`, `agent/` à l'intérieur (structure initialement retenue avant cette clarification) — rejeté : ne matérialise pas physiquement la séparation bibliothèque/façades, une façade pourrait importer un module interne d'une autre façade sans qu'aucun outil ne le signale. | |
| 49 | +- Poetry avec dépendances de chemin (`path = "../regine-core"`) — alternative valable, écosystème plus ancien et plus répandu ; non retenue par préférence pour la rapidité et la simplicité de configuration de `uv`, mais ce choix n'est pas structurant pour la conception elle-même et pourrait être révisé sans impact sur `data-model.md`/`contracts/`. | |
| 50 | +- Dépôts séparés (un par façade) — rejeté : complique la coordination des changements d'API de `regine-core` avec ses façades, alors que le projet est encore à un stade où bibliothèque et façades évoluent ensemble ; un monorepo reste plus simple à faire évoluer tant qu'aucune façade n'a de cycle de release indépendant. | |
| 51 | + | |
| 52 | +## Résumé | |
| 53 | + | |
| 54 | +Tous les points marqués `NEEDS CLARIFICATION` dans le Technical Context du plan sont résolus par les décisions ci-dessus. Aucune dépendance tierce Python nouvelle n'est introduite pour le code de `regine-core`/`regine-cli` ; `uv` est un outil de développement/workspace (pas une dépendance runtime des paquets) introduit par la décision § 5. | |
| new file mode 100644 | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | +# Research: Configuration du contexte de travail de Régine | ||
| 2 | + | ||
| 3 | +## 1. Plateforme cible et déclenchement du montage natif SMB | ||
| 4 | + | ||
| 5 | +**Decision**: Prioriser macOS pour cette itération. Le déclenchement du montage se fait via `open smb://<hôte>/<partage>` (ouvre le mécanisme natif de montage de Finder, avec authentification gérée entièrement par l'OS) ; la détection de disponibilité consiste à vérifier l'accessibilité du point de montage local avant chaque opération nécessitant l'archive. Le mécanisme est isolé derrière une interface (`src/regine/config/smb.py`) pour permettre d'ajouter Windows (`net use` / explorateur) et Linux (`gio mount smb://...`) plus tard sans toucher au reste du module. | ||
| 6 | + | ||
| 7 | +**Rationale**: Le poste de développement et d'usage actuel du projet est macOS ; Windows/Linux ne sont mentionnés dans les notes de conception que comme options futures pour la GUI (PySide6 vs web), jamais comme cible immédiate. Isoler le mécanisme derrière une interface respecte le Principe VI de la constitution (bibliothèque centrale, façades minces) et le principe de simplicité déjà appliqué ailleurs dans le projet (pas de mécanisme pour des cas hypothétiques non encore demandés). | ||
| 8 | + | ||
| 9 | +**Alternatives considered**: | ||
| 10 | +- Gérer soi-même le montage SMB multiplateforme via une bibliothèque tierce (`pysmb`, `smbprotocol`) — rejeté : la clarification du 2026-09-18 sur cette spec exclut explicitement que Régine gère ou stocke des identifiants réseau ; cette responsabilité reste déléguée à l'OS. | ||
| 11 | +- Implémenter les trois OS dès cette itération — rejeté pour limiter la portée initiale ; l'abstraction retenue permet de le faire plus tard sans re-conception. | ||
| 12 | + | ||
| 13 | +## 2. Schéma de la base de contexte centralisée (SQLite) | ||
| 14 | + | ||
| 15 | +**Decision**: Réutiliser les conventions déjà actées par la constitution pour le manifeste persistant par dossier (§ Workflow d'archivage, section 12 des notes de conception) : un fichier SQLite unique, `PRAGMA user_version` pour le numéro de schéma, `PRAGMA application_id` pour marquer le format Régine, écriture transactionnelle. Table principale `boitiers` : identifiant interne, modèle EXIF, numéro de série EXIF (nullable), nom lisible (nullable), horodatage de première rencontre. Unicité sur (modèle, numéro de série) quand le numéro de série est exploitable, sinon sur le modèle seul tant qu'aucune collision réelle ne force une distinction plus fine (cohérent avec `specs/002-profil-boitiers-optionnel`). | ||
| 16 | + | ||
| 17 | +**Rationale**: Cohérence avec le mécanisme déjà retenu pour les bases par dossier (mêmes garanties transactionnelles, même stratégie de version de format) plutôt que d'inventer un second mécanisme de persistance pour un besoin très proche ; SQLite est explicitement le format recommandé par la constitution pour l'archivage long terme. | ||
| 18 | + | ||
| 19 | +**Alternatives considered**: | ||
| 20 | +- Fichier JSON pour la base de contexte — rejeté : pas d'écriture transactionnelle, risque de corruption en cas de coupure, alors que c'est précisément ce que le choix SQLite du projet cherche à éviter ailleurs. | ||
| 21 | +- Une table dans la même base SQLite qu'un manifeste de dossier — rejeté : la base de contexte centralisée n'est pas liée à un dossier particulier et ne doit pas être archivée avec lui (cf. Assumptions de la spec). | ||
| 22 | + | ||
| 23 | +## 3. Validation des répertoires (existence, écriture, espace disque) | ||
| 24 | + | ||
| 25 | +**Decision**: Utiliser les primitives standard de Python (`pathlib.Path.exists`/`mkdir`, `os.access`, `shutil.disk_usage`) pour vérifier l'existence, la capacité d'écriture et l'espace disponible avant toute opération de configuration ou d'initialisation de la base de données de travail. | ||
| 26 | + | ||
| 27 | +**Rationale**: Ces vérifications sont simples et entièrement couvertes par la bibliothèque standard ; le projet préfère des dépendances minimales (cf. Principe VI, pas de complexité non justifiée). | ||
| 28 | + | ||
| 29 | +**Alternatives considered**: | ||
| 30 | +- Bibliothèque tierce de gestion de systèmes de fichiers multiplateforme — rejeté, complexité non justifiée pour un besoin déjà couvert nativement. | ||
| 31 | + | ||
| 32 | +## 4. Convention de surface CLI | ||
| 33 | + | ||
| 34 | +**Decision**: Sous-commandes `regine config set-paths`, `regine config show`, `regine config cameras list`, `regine config cameras rename`, suivant les conventions CLI Unix standard déjà actées par la constitution (arguments/flags en entrée, texte sur stdout, erreurs sur stderr, code de sortie non-zéro en cas d'échec). | ||
| 35 | + | ||
| 36 | +**Rationale**: Cohérence avec la contrainte technique CLI-first déjà actée (protocole texte in/out) ; pas de nouvelle convention à inventer. | ||
| 37 | + | ||
| 38 | +**Alternatives considered**: | ||
| 39 | +- Fichier de configuration statique édité à la main (YAML/TOML), sans commande dédiée — rejeté : contredit FR-003 (proposer de créer les répertoires), FR-004/FR-005 (détection et mémorisation dynamiques du montage SMB) et FR-010 (refus actif d'un changement tant qu'un travail n'est pas réconcilié), qui impliquent une logique active plutôt qu'un simple fichier statique. | ||
| 40 | + | ||
| 41 | +## 5. Organisation monorepo (bibliothèque centrale + 3 façades) | ||
| 42 | + | ||
| 43 | +**Decision**: Adopter un monorepo à quatre paquets Python indépendants et installables séparément : `regine-core` (bibliothèque centrale, toute la logique métier), `regine-cli`, `regine-gui`, `regine-agent` (façades, chacune dépendant de `regine-core` sans logique métier propre). Outillage de workspace : `uv` (gestion de dépendances et lockfile unique au niveau du dépôt, `uv.lock`), avec un `pyproject.toml` par paquet sous `packages/<nom>/` suivant le format standard PEP 621. `regine-gui` et `regine-agent` sont créés comme paquets vides (dépendance déclarée, aucun code métier) pour réserver la structure dès cette itération, sans être implémentés maintenant. | ||
| 44 | + | ||
| 45 | +**Rationale**: La demande explicite est de penser dès maintenant la place des 4 parties techniques (lib, CLI, GUI, agent IA) plutôt que de les découvrir au fur et à mesure. Un monorepo à paquets séparés rend le Principe VI (bibliothèque centrale, façades minces) vérifiable structurellement : une façade qui importerait autre chose que l'API publique de `regine-core` serait une violation visible dès la déclaration des dépendances du paquet, pas seulement une convention à surveiller par relecture. `uv` est l'outil de gestion de paquets/workspace Python le plus rapide et le plus simple à opérer à la date de ce plan, avec un support natif des workspaces multi-paquets et un lockfile unique — cohérent avec la préférence du projet pour des dépendances minimales et une exécution sans démon (pas de service d'outillage à faire tourner, juste un binaire). | ||
| 46 | + | ||
| 47 | +**Alternatives considered**: | ||
| 48 | +- Un seul paquet `src/regine/` avec des sous-modules `cli/`, `gui/`, `agent/` à l'intérieur (structure initialement retenue avant cette clarification) — rejeté : ne matérialise pas physiquement la séparation bibliothèque/façades, une façade pourrait importer un module interne d'une autre façade sans qu'aucun outil ne le signale. | ||
| 49 | +- Poetry avec dépendances de chemin (`path = "../regine-core"`) — alternative valable, écosystème plus ancien et plus répandu ; non retenue par préférence pour la rapidité et la simplicité de configuration de `uv`, mais ce choix n'est pas structurant pour la conception elle-même et pourrait être révisé sans impact sur `data-model.md`/`contracts/`. | ||
| 50 | +- Dépôts séparés (un par façade) — rejeté : complique la coordination des changements d'API de `regine-core` avec ses façades, alors que le projet est encore à un stade où bibliothèque et façades évoluent ensemble ; un monorepo reste plus simple à faire évoluer tant qu'aucune façade n'a de cycle de release indépendant. | ||
| 51 | + | ||
| 52 | +## Résumé | ||
| 53 | + | ||
| 54 | +Tous les points marqués `NEEDS CLARIFICATION` dans le Technical Context du plan sont résolus par les décisions ci-dessus. Aucune dépendance tierce Python nouvelle n'est introduite pour le code de `regine-core`/`regine-cli` ; `uv` est un outil de développement/workspace (pas une dépendance runtime des paquets) introduit par la décision § 5. | ||