# osx-backup — suivi post-implémentation (2026-09-03)

État : 16 tâches implémentées et reviewées, vague de correctifs finale validée, 242 tests verts. Ce fichier liste les points mineurs différés par les reviews, à traiter au fil de l'eau.

## Mineurs différés par tâche

- Task 1: minor (deferred): test_scaffold n'asserte pas Path.home()==fake_home (plan-mandated)
- Task 2: minor (deferred): docstring stream non-raw (\r \n littéraux, runner.py) ; kill enfant direct seulement + join sans timeout si on_line lève
- Task 3: minor (deferred): motifs `x/` (slash final) et `a/**/b` non gitignore-style dans is_excluded — à noter pour les listes d'exclusion des tâches suivantes
- Task 4: minor (deferred): register() écrase un doublon silencieusement ; docstring « module stateless, état dans ctx » à ajouter sur Module
- Task 5: minor (deferred): _atomic_write via mkstemp produit des fichiers 0600 (os.fchmod(fd, 0o644) à ajouter) ; pas de test du chemin d'échec de l'écriture atomique
- Task 6: minor (deferred): tests chmod 0 échoueraient sous root ; résidu partiel possible sous <dest>/<module>/<rel> après échec (inerte)
- Task 7: minor (deferred): vérifier le type du membre (issym/isfile) avant place (secrets.py:177-179) ; totaux progress/inventory ne suivent pas les symlinks-dossiers alors que l'archive les déréférence ; a/../b refusé avec message « hors de $HOME » trompeur ; UI devra distinguer « entrées » (inventory) et « fichiers » (backup/restore items)
- Task 8: minor (deferred): vscode-extensions.txt obsolète conservé si `code` absent au backup ; warnings « absent » pour chemins optionnels (Ghostty, keybindings, snippets) — flag optional sur PathItem à envisager avant que la CLI affiche les warnings d'inventaire ; incohérence available=False (claude sans ~/.claude) vs available=True (editors sans éditeur) ; stderr omis dans le warning backup ; tests manquants (readonly list, code absent au restore, ~/.claude absent)
- Task 9: minor (deferred): PROGRESS_RE assoupli peut prendre une ligne `nom NN%` pour de la progression si -v est injecté ; stderr rsync loggé deux fois une fois RealRunner(log=ctx.log) câblé (Task 15) ; mkdir redondant dans _mirror
- Task 11: minor (deferred): dumps orphelins de bases disparues non purgés dans <dest>/postgres ; test live suppose un rôle = utilisateur OS ; résultat brew services start ignoré ; labels progress bruts
- Task 12: minor (deferred): stopped assigné après _stop_containers (exception OS pendant l'arrêt → pas de restart) ; parse_labels sur virgule ; états restarting/paused ; restore sur volume existant ; images <none> ; test d'injection sur le 2e volume manquant
- Task 15: minor (deferred): /System/Volumes/Data accepté comme dest ; log créé pendant l'inventaire même si Ctrl-C au prompt ; duplication backup/restore ; second Ctrl-C en écriture ; source restore non vérifiée inscriptible ; --yes ignore last_selection
- Task 16: minor (deferred, à trier en review finale): dry-run affiche « miroir à jour » pour github/documents ; secrets chiffre réellement en dry-run (~10 s) ; warnings de build_archive absents de la colonne Avert. du résumé ; warning socket agent à chaque backup
- Task 16: minor (deferred): tree_size compte sockets/fifos → barre secrets finit à N-1 ; warnings build_archive absents de ModuleResult.warnings ; ajouter **/.ssh/agent aux exclusions (décision utilisateur)

## Résidus de la review finale (parqués avec ruling)

- Re-review vague finale : 12/12 addressed, aucun Critical/Important. Résidus parqués — Ruling: le chemin d'échec de prefetch_passphrase (passphrase vide/différente, ou --yes sans env) re-demande sous le spinner ou échoue en fin de run : réel, différé, non porteur ; coût si faux : gêne visuelle. Ruling: message C1 trompeur après un premier run tué sans manifeste (--force nécessaire) : réel, différé ; coût si faux : un --force. Ruling: path "" ou "." accepté par _checked_path (copie $HOME entier dans <dest>/dotfiles, pas destructif) : différé. Ruling: restore --dry-run avec secrets demande la passphrase sous le live display, write_manifest sur source en lecture seule lève : différés.
