Compare commits

...

3 commits

Author SHA1 Message Date
le king fu
6e8e15719c state: sync after the Linux update cycle of v0.17.2 and #421
Max ran the real update cycle v0.17.1 -> v0.17.2 on Linux (.deb):
it worked, and a password prompt appeared (its type was not noted).
The trace is in the v0.17.2 release body. #421 was checked on Linux
and closed by hand (comment 25074). Windows and .rpm cycles remain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:51:27 -04:00
le king fu
af68d0623f state: pilot ranks of #464 and #465, mark v0.17.2 as published
The #458 pilot table (comment 24819) now has four rows: #459, #450,
#464 and #465, the last two judged right at the high level by Max.
#464 and #465 were counted second and third here without #450.
Entries merged since v0.17.1 now say they shipped in v0.17.2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:36:45 -04:00
le king fu
34ca76d4bf state: sync after v0.17.2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 15:14:08 -04:00

View file

@ -1,8 +1,8 @@
# STATE — Simpl'Résultat
> Derniere MAJ : 2026-10-18 (**#421 mergée, issue ouverte jusqu'à la vérification manuelle — les six confirmations attendent la réponse (`confirmAction()` sur `ask` de `@tauri-apps/plugin-dialog`), PR #465 en avance rapide par l'API, `main` `ff9656d`.** Supprimer un profil secondaire effaçait sa base même sur « Annuler ». Les deux prérequis du tag de la v0.17.2, #419 et #421, sont mergés ; vérification manuelle de #421 due sur la release, puis fermeture à la main. Troisième PR mesurée du pilote #458. Suivi #467. Aucune migration (v1→v17).)
> Derniere MAJ : 2026-10-18 (**Étape 10 faite sous Linux et #421 fermée — cycle réel v0.17.1 → v0.17.2 réussi (`.deb`, invite de mot de passe vue, type non consigné), trace dans le corps de la release ; #421 vérifiée sous Linux par Max, fermée à la main (commentaire 25074).** Restent les cycles Windows et `.rpm`, et les vérifications dans l'app de #369 et des retours de la v0.17.1, non confirmées à ce jour. Aucune migration (v1→v17).)
>
> Précédente MAJ : 2026-10-18 (**#419 mergée et fermée — `latest.json` vide ou à plusieurs documents refusé avant le `DELETE` du registre, étape « Publish » exécutée par les tests, PR #464 en avance rapide par l'API, `main` `c859405`.** Le blocker « avant le prochain tag : #419, point 1 » est levé ; `check-frontend` ne saute plus `.claude/**` ni `release.yml` (décision de Max), déclencheur pas encore prouvé par une PR qui ne toucherait que ces chemins. Deuxième PR mesurée du pilote #458. Aucune migration (v1→v17).)
> Précédente MAJ : 2026-10-18 (**Relevé du pilote #458 à 4 PR sur 20 : #464 et #465 ajoutées au tableau (commentaire 24819), niveau haut jugé juste par Max pour les deux ; rangs corrigés ici (#450 était la deuxième, #464 est la troisième, #465 la quatrième).** Les PR mergées depuis la v0.17.1 sont marquées publiées dans la v0.17.2. Vérifications dans l'app et étape 10 en cours chez Max, concluantes à date. Aucune migration (v1→v17).)
## Position actuelle
@ -30,30 +30,33 @@ Audit critique de la page Bilan livré (`docs/audit-bilan-2026-05.md`, revue CPA
**v0.17.1 shippée** (2026-10-08, tag `v0.17.1` sur `e4db715` → CI release run 508, 7 artefacts + `latest.json` vérifiés par `verify-release.sh`, endpoint de l'updater en 0.17.1) — parcours de démarrage guidé et #390 (étape 5 de la liste, rattrapage des migrations des profils secondaires, dossier des bases sous Linux). Numéro de correctif choisi par Max malgré les entrées Added. `[Unreleased]` vidé au tag. Aucune migration DB nouvelle (v1→v17). Étape 10 de `/release` non exigée (chaîne de mise à jour inchangée), raison écrite sur la release. Vérifications manuelles faites sur la release publiée (parcours guidé, #390), complétion confirmée le 2026-10-10.
**Chaîne de release et dépendances mergée sur `main`** (2026-10-12, `9e8c41b`, pas encore publiée) — milestone `planned-2026-10-10-release-deps` fermée 4/4 (#376, #345, #320, #358, plus #317 ; PRs #414 → #417 produites par `/autopilot` le 2026-10-10 et relues par quatre `/pr-review` APPROVE, puis PR #418 de suivis des revues, relue à son tour) : Node 24 dans les trois workflows encore en Node 20 ; garde `Verify windows-sys pinning` dans `check-rust` (ADR 0023) ; `latest.json` avec une clé par paquet Linux (`linux-x86_64-deb`, `linux-x86_64-rpm`) et sans clé générique, contrôlé avant le `DELETE` du registre par `scripts/check-latest-json.jq` ; lock npm rafraîchi, `npm audit` à 0. Aucune migration DB (v1→v17). `[Unreleased]` porte un Corrigé (#320) et un Sécurité (#358). Suivi : #419 (point 1 avant le prochain tag).
**Chaîne de release et dépendances mergée sur `main`** (2026-10-12, `9e8c41b`, publiée dans la v0.17.2) — milestone `planned-2026-10-10-release-deps` fermée 4/4 (#376, #345, #320, #358, plus #317 ; PRs #414 → #417 produites par `/autopilot` le 2026-10-10 et relues par quatre `/pr-review` APPROVE, puis PR #418 de suivis des revues, relue à son tour) : Node 24 dans les trois workflows encore en Node 20 ; garde `Verify windows-sys pinning` dans `check-rust` (ADR 0023) ; `latest.json` avec une clé par paquet Linux (`linux-x86_64-deb`, `linux-x86_64-rpm`) et sans clé générique, contrôlé avant le `DELETE` du registre par `scripts/check-latest-json.jq` ; lock npm rafraîchi, `npm audit` à 0. Aucune migration DB (v1→v17). `[Unreleased]` porte un Corrigé (#320) et un Sécurité (#358). Suivi : #419 (point 1 avant le prochain tag).
**#423 mergée sur `main`** (2026-10-12, `8898213`, pas encore publiée) — les champs « Catégorie parente » (formulaire de catégorie) et « Catégorie » (dialogue « Nouveau mot-clé ») utilisent `CategoryCombobox` : saisie qui filtre, ordre hiérarchique, noms du seed traduits. Liste des parents : racines et niveau 1, moins la catégorie éditée, profondeur réduite de la hauteur de son sous-arbre (pas de 4ᵉ niveau), parent courant toujours gardé ; seule garde aujourd'hui, `updateCategory` ne vérifie rien (#393). Le dialogue mot-clé prend la liste des Transactions (actives et saisissables, D2) et ne garde la catégorie pré-remplie que si elle en fait partie. `[Unreleased]` porte un Modifié. Suivi : #429. Aucune migration (v1→v17).
**#423 mergée sur `main`** (2026-10-12, `8898213`, publiée dans la v0.17.2) — les champs « Catégorie parente » (formulaire de catégorie) et « Catégorie » (dialogue « Nouveau mot-clé ») utilisent `CategoryCombobox` : saisie qui filtre, ordre hiérarchique, noms du seed traduits. Liste des parents : racines et niveau 1, moins la catégorie éditée, profondeur réduite de la hauteur de son sous-arbre (pas de 4ᵉ niveau), parent courant toujours gardé ; seule garde aujourd'hui, `updateCategory` ne vérifie rien (#393). Le dialogue mot-clé prend la liste des Transactions (actives et saisissables, D2) et ne garde la catégorie pré-remplie que si elle en fait partie. `[Unreleased]` porte un Modifié. Suivi : #429. Aucune migration (v1→v17).
**Fiabilité des tests et de `db.ts` mergée sur `main`** (2026-10-13, `c17bf5d`, pas encore publiée) — milestone `planned-2026-10-10-fiabilite-tests` fermée 4/4 (#408, #409, #389, #395 ; PRs #433 → #436 produites par `/autopilot` le 2026-10-12, relues par quatre `/pr-review` APPROVE, cinq commits de suivi en tête de pile) : `withTransaction` remet au rappel son propre handle, révoqué à la fin, toute autre requête attend derrière le verrou ; changement de profil en une seule section exclusive avec numéro de génération ; alerte Journal après 15 s d'attente ; harnais `src/test/hookHarness.ts` et faux `t` marqué `src/test/i18nMock.ts`, gardé par `src/__integration__/i18n-mock-guard.test.ts` ; le Journal nomme la copie d'un rattrapage arrêté et ne contient plus de chemin, une seule copie gardée par profil, la page d'erreur du démarrage disparaît quand le profil s'ouvre après le délai ; badge « non garanti » traduit. `[Unreleased]` porte un Modifié et deux Corrigé de plus. Suivi : #437. Aucune migration (v1→v17).
**Fiabilité des tests et de `db.ts` mergée sur `main`** (2026-10-13, `c17bf5d`, publiée dans la v0.17.2) — milestone `planned-2026-10-10-fiabilite-tests` fermée 4/4 (#408, #409, #389, #395 ; PRs #433 → #436 produites par `/autopilot` le 2026-10-12, relues par quatre `/pr-review` APPROVE, cinq commits de suivi en tête de pile) : `withTransaction` remet au rappel son propre handle, révoqué à la fin, toute autre requête attend derrière le verrou ; changement de profil en une seule section exclusive avec numéro de génération ; alerte Journal après 15 s d'attente ; harnais `src/test/hookHarness.ts` et faux `t` marqué `src/test/i18nMock.ts`, gardé par `src/__integration__/i18n-mock-guard.test.ts` ; le Journal nomme la copie d'un rattrapage arrêté et ne contient plus de chemin, une seule copie gardée par profil, la page d'erreur du démarrage disparaît quand le profil s'ouvre après le délai ; badge « non garanti » traduit. `[Unreleased]` porte un Modifié et deux Corrigé de plus. Suivi : #437. Aucune migration (v1→v17).
**Retours d'onboarding de la v0.17.1 mergés sur `main`** (2026-10-15, `934bcbf`, pas encore publiés) — milestone `planned-2026-10-12-retours-onboarding-v0171` fermée 8/8 (#424, #422, #427, #426, #430, #431, #425, #432 ; PRs #438 → #445 produites par `/autopilot` le 2026-10-13, relues par huit `/pr-review` APPROVE sans bloquant) : grille Budget émise en profondeur et sous-totaux en bas rattachés à leur bloc (`reorderRows`, corrige aussi Budget vs réel et Comparables) ; encadré « Structure attendue » (un sous-dossier par compte), avertissement des CSV posés à la racine (`scan_import_folder` → `ImportFolderScan`), nom de source en lecture seule = sous-dossier ; cartes Transactions (« Ajouter comme mot-clé ») et Budget (feuilles, colonne Annuel) ; aide et guide périmés corrigés ; parcours à huit lignes avec deux étapes de visite (Catégories, Rapports) cochées par « J'ai compris » ou un clic sur Tendances, initialisées une fois par profil sans transaction (ADR 0022 amendé). `[Unreleased]` porte des Added, Changed et Fixed de plus. Suivi : #446. Aucune migration (v1→v17).
**Retours d'onboarding de la v0.17.1 mergés sur `main`** (2026-10-15, `934bcbf`, publiés dans la v0.17.2) — milestone `planned-2026-10-12-retours-onboarding-v0171` fermée 8/8 (#424, #422, #427, #426, #430, #431, #425, #432 ; PRs #438 → #445 produites par `/autopilot` le 2026-10-13, relues par huit `/pr-review` APPROVE sans bloquant) : grille Budget émise en profondeur et sous-totaux en bas rattachés à leur bloc (`reorderRows`, corrige aussi Budget vs réel et Comparables) ; encadré « Structure attendue » (un sous-dossier par compte), avertissement des CSV posés à la racine (`scan_import_folder` → `ImportFolderScan`), nom de source en lecture seule = sous-dossier ; cartes Transactions (« Ajouter comme mot-clé ») et Budget (feuilles, colonne Annuel) ; aide et guide périmés corrigés ; parcours à huit lignes avec deux étapes de visite (Catégories, Rapports) cochées par « J'ai compris » ou un clic sur Tendances, initialisées une fois par profil sans transaction (ADR 0022 amendé). `[Unreleased]` porte des Added, Changed et Fixed de plus. Suivi : #446. Aucune migration (v1→v17).
**#447 mergée sur `main`** (2026-10-16, `1763a9f`, pas encore publiée) — `rustls` 0.23.45 → 0.23.46 (PR #448 : deux lignes de `Cargo.lock`, aucun bump compagnon, aucune arête `windows-sys` déplacée) corrige RUSTSEC-2026-0346 à -0349, publiées le 2026-10-14, qui rougissaient `audit.yml` depuis le 2026-10-15 sans que le lock ait bougé depuis la v0.17.1. Aucune des quatre n'est atteignable (`rustls` n'est atteint que par `tauri-plugin-updater` → `reqwest` 0.13), mais la règle 1 de `.cargo/audit.toml` demande de corriger plutôt que de supprimer ; `audit.yml` est de nouveau vert sur `main` (run 556). Pas de release corrective : le bump part avec le prochain tag, qui devra dérouler le cycle réel de mise à jour. `[Unreleased]` porte un second Sécurité. Suivis : #449 et agent-defenseurs#186. Aucune migration (v1→v17).
**#447 mergée sur `main`** (2026-10-16, `1763a9f`, publiée dans la v0.17.2) — `rustls` 0.23.45 → 0.23.46 (PR #448 : deux lignes de `Cargo.lock`, aucun bump compagnon, aucune arête `windows-sys` déplacée) corrige RUSTSEC-2026-0346 à -0349, publiées le 2026-10-14, qui rougissaient `audit.yml` depuis le 2026-10-15 sans que le lock ait bougé depuis la v0.17.1. Aucune des quatre n'est atteignable (`rustls` n'est atteint que par `tauri-plugin-updater` → `reqwest` 0.13), mais la règle 1 de `.cargo/audit.toml` demande de corriger plutôt que de supprimer ; `audit.yml` est de nouveau vert sur `main` (run 556). Pas de release corrective : le bump part avec le prochain tag, qui devra dérouler le cycle réel de mise à jour. `[Unreleased]` porte un second Sécurité. Suivis : #449 et agent-defenseurs#186. Aucune migration (v1→v17).
**#369 mergée sur `main`** (2026-10-17, `a8c3fd6`, pas encore publiée) — la Répartition (bouton de la page Transactions) est réservée à l'édition Base, comme l'écran de déverrouillage le promettait (`upsell.features.adjustments`) : en Gratuite, le bouton garde sa place, porte un cadenas et ouvre l'écran verrouillé dans une fenêtre (`UpsellDialog`) au lieu de la fenêtre de répartition, pour toute ligne ; tant que la licence n'est pas `ready`, bouton inactif, ni cadenas ni fenêtre ; les répartitions existantes restent comptées et gardent l'icône orange. Pièces : `splitAccessFor` (`src/shared/splitGate.ts`, `open`/`locked`/`pending`, plus strict que `profileGate` : `allowed` ne court-circuite pas `ready`) et la constante `SPLIT_FEATURE`, `SplitButton`, `UpsellDialog`, prop `splitAccess` obligatoire de `TransactionTable`, calculée par `TransactionsPage` depuis `useEntitlement(SPLIT_FEATURE)` ; ADR 0017 amendé, guide, docs intégrées FR/EN et `architecture.md` à jour, `[Unreleased]` porte un Modifié de plus. Suivis : #451 (fenêtre d'incitation de `ProfileSwitcher` sur `UpsellDialog`, Échap, focus) et #454 (reclasser une transaction répartie laisse sa ligne de compensation dans l'ancienne catégorie, irréparable en Gratuite depuis #369). Aucune migration (v1→v17).
**#369 mergée sur `main`** (2026-10-17, `a8c3fd6`, publiée dans la v0.17.2) — la Répartition (bouton de la page Transactions) est réservée à l'édition Base, comme l'écran de déverrouillage le promettait (`upsell.features.adjustments`) : en Gratuite, le bouton garde sa place, porte un cadenas et ouvre l'écran verrouillé dans une fenêtre (`UpsellDialog`) au lieu de la fenêtre de répartition, pour toute ligne ; tant que la licence n'est pas `ready`, bouton inactif, ni cadenas ni fenêtre ; les répartitions existantes restent comptées et gardent l'icône orange. Pièces : `splitAccessFor` (`src/shared/splitGate.ts`, `open`/`locked`/`pending`, plus strict que `profileGate` : `allowed` ne court-circuite pas `ready`) et la constante `SPLIT_FEATURE`, `SplitButton`, `UpsellDialog`, prop `splitAccess` obligatoire de `TransactionTable`, calculée par `TransactionsPage` depuis `useEntitlement(SPLIT_FEATURE)` ; ADR 0017 amendé, guide, docs intégrées FR/EN et `architecture.md` à jour, `[Unreleased]` porte un Modifié de plus. Suivis : #451 (fenêtre d'incitation de `ProfileSwitcher` sur `UpsellDialog`, Échap, focus) et #454 (reclasser une transaction répartie laisse sa ligne de compensation dans l'ancienne catégorie, irréparable en Gratuite depuis #369). Aucune migration (v1→v17).
**`REVIEW.md` mergé sur `main`** (2026-10-18, `24da72b`) — niveau d'une PR (haut, normal, bas) fixé par les fichiers que touche son diff, jamais par son auteur ; tableau Haut de 21 lignes (licence et jetons, migrations et bases de profils, release et code exécuté avec la clé de signature, dépendances qui changent la confiance, CI qui pourrait passer au vert à tort, `.claude/settings.json` et `.mcp.json`, et une règle qui échoue fermée pour tout fichier ajouté, renommé ou supprimé à la racine ou directement dans `src-tauri/`) ; neuf zones, chaque règle sourcée par une section du `CLAUDE.md` ou un ADR ; commandes de vérification ; onze pièges, dont les trois du skill global `pr-review`, corrigés pour ce dépôt ; script de calibration versionné `scripts/review-levels.py` (`--check` compare ses motifs au tableau). `CLAUDE.md` y renvoie. Depuis #457 (fermée le 2026-10-18), `/pr-review` le lit sur `main` et annonce le niveau en tête de chaque verdict ; le pilote #458 mesure les 20 PR suivantes, la première étant #459. Suivis : #461 et #462. Aucune migration (v1→v17).
**`REVIEW.md` mergé sur `main`** (2026-10-18, `24da72b`) — niveau d'une PR (haut, normal, bas) fixé par les fichiers que touche son diff, jamais par son auteur ; tableau Haut de 21 lignes (licence et jetons, migrations et bases de profils, release et code exécuté avec la clé de signature, dépendances qui changent la confiance, CI qui pourrait passer au vert à tort, `.claude/settings.json` et `.mcp.json`, et une règle qui échoue fermée pour tout fichier ajouté, renommé ou supprimé à la racine ou directement dans `src-tauri/`) ; neuf zones, chaque règle sourcée par une section du `CLAUDE.md` ou un ADR ; commandes de vérification ; onze pièges, dont les trois du skill global `pr-review`, corrigés pour ce dépôt ; script de calibration versionné `scripts/review-levels.py` (`--check` compare ses motifs au tableau). `CLAUDE.md` y renvoie. Depuis #457 (fermée le 2026-10-18), `/pr-review` le lit sur `main` et annonce le niveau en tête de chaque verdict ; le pilote #458 mesure les 20 PR suivantes, la première étant #459 ; relevé au 2026-10-18 (commentaire 24819) : 4 sur 20, #459, #450, #464 et #465, toutes de niveau haut, jugé juste par Max sauf pour #450 (trop haut, #462). Suivis : #461 et #462. Aucune migration (v1→v17).
**#455 mergée sur `main`** (2026-10-18, `c5efc38`, pas encore publiée) — `tauri-plugin-updater` compilé sans sa feature `zip` (`default-features = false`, `rustls-tls` gardé) : `zip`, `arbitrary` et `derive_arbitrary` sortent du lock (666 → 663 paquets, aucun ajouté), et avec eux RUSTSEC-2026-0367 à -0369, retirés et non supprimés dans `.cargo/audit.toml` ; `tar` quitte le graphe Linux, d'où le canari de la garde des suppressions de `check-rust` passé de `tar` à `webkit2gtk` (ADR 0018 amendé ; `architecture.md`, `docs/qa-update-cycle.md` et skill `/release` à jour). `[Unreleased]` porte un troisième Sécurité. `audit.yml` vert sur `main` (run 564). Suivi : #463. Aucune migration (v1→v17).
**#455 mergée sur `main`** (2026-10-18, `c5efc38`, publiée dans la v0.17.2) — `tauri-plugin-updater` compilé sans sa feature `zip` (`default-features = false`, `rustls-tls` gardé) : `zip`, `arbitrary` et `derive_arbitrary` sortent du lock (666 → 663 paquets, aucun ajouté), et avec eux RUSTSEC-2026-0367 à -0369, retirés et non supprimés dans `.cargo/audit.toml` ; `tar` quitte le graphe Linux, d'où le canari de la garde des suppressions de `check-rust` passé de `tar` à `webkit2gtk` (ADR 0018 amendé ; `architecture.md`, `docs/qa-update-cycle.md` et skill `/release` à jour). `[Unreleased]` porte un troisième Sécurité. `audit.yml` vert sur `main` (run 564). Suivi : #463. Aucune migration (v1→v17).
**#419 mergée sur `main`** (2026-10-18, `c859405`, pas encore publiée) — `scripts/check-latest-json.jq` exige exactement un document (`length == 1 and (.[0] | …)`) et l'étape « Publish » de `release.yml` l'appelle avec `-s` : sous jq 1.6, la version du conteneur de release, un `latest.json` vide passait (rc 0) et un fichier à deux documents était jugé sur le dernier. `scripts/build-latest-json.test.mjs` (28 → 36 tests) exécute le texte exact de l'étape « Publish » avec un `curl` factice : `DELETE` puis `PUT` sur un manifeste valide, sortie 1 sans aucune requête sur un refus. `check-frontend` ne saute plus `.claude/**` ni `release.yml` (`REVIEW.md`, `CLAUDE.md` et `architecture.md` à jour) ; commentaire périmé de `release.yml:104` corrigé (point 3 de #461) ; `docs/qa-update-cycle.md` note qu'un build `tauri dev` sous Linux affiche `TargetsNotFound`, attendu depuis #418. Aucune entrée de CHANGELOG (rien de visible pour l'utilisateur). Aucune migration (v1→v17).
**#419 mergée sur `main`** (2026-10-18, `c859405`, publiée dans la v0.17.2) — `scripts/check-latest-json.jq` exige exactement un document (`length == 1 and (.[0] | …)`) et l'étape « Publish » de `release.yml` l'appelle avec `-s` : sous jq 1.6, la version du conteneur de release, un `latest.json` vide passait (rc 0) et un fichier à deux documents était jugé sur le dernier. `scripts/build-latest-json.test.mjs` (28 → 36 tests) exécute le texte exact de l'étape « Publish » avec un `curl` factice : `DELETE` puis `PUT` sur un manifeste valide, sortie 1 sans aucune requête sur un refus. `check-frontend` ne saute plus `.claude/**` ni `release.yml` (`REVIEW.md`, `CLAUDE.md` et `architecture.md` à jour) ; commentaire périmé de `release.yml:104` corrigé (point 3 de #461) ; `docs/qa-update-cycle.md` note qu'un build `tauri dev` sous Linux affiche `TargetsNotFound`, attendu depuis #418. Aucune entrée de CHANGELOG (rien de visible pour l'utilisateur). Aucune migration (v1→v17).
**#421 mergée sur `main`** (2026-10-18, `ff9656d`, pas encore publiée, issue ouverte jusqu'à la vérification manuelle) — sur desktop, le script d'initialisation de `tauri-plugin-dialog` 2.6.0 remplace `window.confirm` par une fonction asynchrone : `confirm(...)` rendait une promesse, toujours vraie, et six confirmations laissaient l'action partir avant la réponse (profil et sa base supprimés même sur « Annuler » ; suppressions de catégorie, d'ajustement, de modèle de budget et de catégorie du Bilan ; les deux confirmations du retrait de la clé de licence), dans toutes les versions publiées. `confirmAction()` (`src/services/confirmService.ts`) appelle `ask` de `@tauri-apps/plugin-dialog` 2.6.0 (ajouté à `package.json` à la version du crate, une seule clé de lock) avec une icône d'avertissement et les boutons `common.confirm` et `common.cancel` dans la langue de l'app ; un échec vaut refus et passe par `logWarn`. Les six sites l'attendent avec `await`, et `performRemoveLicense` prend une confirmation asynchrone. Garde `src/__integration__/native-dialog-guard.test.ts` (34 tests) : aucun `confirm` ni `alert` natif dans `src/` (nu, par `window`, `globalThis` ou `self`, en `?.(`, par index, déstructuré), toute confirmation attendue, aucune autre mention de `confirmAction` (alias). `architecture.md` à jour (service, ligne du plugin) ; `[Unreleased]` porte un Corrigé de plus. Suivi : #467. Aucune migration (v1→v17).
**#421 mergée sur `main`** (2026-10-18, `ff9656d`, publiée dans la v0.17.2, vérifiée sous Linux et fermée le 2026-10-18) — sur desktop, le script d'initialisation de `tauri-plugin-dialog` 2.6.0 remplace `window.confirm` par une fonction asynchrone : `confirm(...)` rendait une promesse, toujours vraie, et six confirmations laissaient l'action partir avant la réponse (profil et sa base supprimés même sur « Annuler » ; suppressions de catégorie, d'ajustement, de modèle de budget et de catégorie du Bilan ; les deux confirmations du retrait de la clé de licence), dans toutes les versions publiées. `confirmAction()` (`src/services/confirmService.ts`) appelle `ask` de `@tauri-apps/plugin-dialog` 2.6.0 (ajouté à `package.json` à la version du crate, une seule clé de lock) avec une icône d'avertissement et les boutons `common.confirm` et `common.cancel` dans la langue de l'app ; un échec vaut refus et passe par `logWarn`. Les six sites l'attendent avec `await`, et `performRemoveLicense` prend une confirmation asynchrone. Garde `src/__integration__/native-dialog-guard.test.ts` (34 tests) : aucun `confirm` ni `alert` natif dans `src/` (nu, par `window`, `globalThis` ou `self`, en `?.(`, par index, déstructuré), toute confirmation attendue, aucune autre mention de `confirmAction` (alias). `architecture.md` à jour (service, ligne du plugin) ; `[Unreleased]` porte un Corrigé de plus. Suivi : #467. Aucune migration (v1→v17).
**v0.17.2 shippée** (2026-10-18, tag `v0.17.2` sur `f42f360` → CI release run 570, 7 artefacts + `latest.json` vérifiés par `verify-release.sh`, endpoint de l'updater en 0.17.2 avec les trois clés `linux-x86_64-deb`, `linux-x86_64-rpm`, `windows-x86_64`) — tout ce qui s'était accumulé depuis la v0.17.1 : retours d'onboarding (#424-#432), Répartition en Base (#369), clé `.rpm` de `latest.json` (#320), Node 24 dans les workflows (#376), garde `windows-sys` (#345), fiabilité des tests et de `db.ts` (#408, #409, #389, #395), menus de catégorie (#423), `rustls` 0.23.46 (#447), updater sans `zip` (#455), garde de `latest.json` sous jq 1.6 (#419), confirmations attendues (#421). Numéro de correctif choisi par Max malgré les entrées Added. `[Unreleased]` vidé au tag. Aucune migration DB nouvelle (v1→v17). Étape 10 de `/release` obligatoire (`release.yml` et `rustls` changent) : cycle Linux `.deb` v0.17.1 → v0.17.2 réussi le 2026-10-18 (Max, trace dans le corps de la release), Windows et `.rpm` pas encore déroulés.
## Decisions recentes
- 2026-10-18 : **#421 mergée — `/fix-issue` (contrôle du plan passé du premier coup) → `/pr-review` APPROVE de niveau haut → un commit de suivi en tête → merge ff par l'API (PR #465, `main` `ff9656d`) : les confirmations attendent la réponse de l'utilisateur ; issue gardée ouverte (`Refs`, `status:blocked`) jusqu'à la vérification manuelle de Max.** Cause : le script d'initialisation desktop de `tauri-plugin-dialog` 2.6.0 remplace `window.confirm` par une fonction asynchrone, donc chaque garde `if (!confirm(...)) return;` testait une promesse, toujours vraie ; défaut présent dans toutes les versions publiées, le plus grave étant la suppression d'un profil secondaire et de sa base sur « Annuler ». Correctif : `confirmAction()` sur `ask` du plugin, un échec valant refus ; `@tauri-apps/plugin-dialog` ajouté à la version du crate, d'où le niveau haut (dépendance ajoutée). `tsc` ne relève pas `!promise` (mutation M1 verte sous `tsc`), d'où la garde `native-dialog-guard.test.ts`. Preuves : reproduction par six tests rouges de `useLicenseMachines.test.ts` avec une confirmation asynchrone ; `ProfileFormModal.delete.test.ts` sur le harnais `hookHarness` ; mutations de l'auteur rouges à 8 sur 8 ; revue (commentaire 24953) avec 8 mutations du relecteur sur 9 rouges, la survivante étant un alias (`const c = confirmAction`). Suggestion 1 appliquée après la revue (`ff9656d`, tests seuls, non relu, nommé dans le commentaire 25025) : l'alias et trois formes natives (`window["confirm"]`, `confirm?.(`, `const { confirm } = window`) sont désormais rouges. Rebase sur `5222329` (PR #450, mergée entre-temps, `SKILL.md` seul) ; `check-frontend` vert sur `ff9656d`, 2297 tests (2256 avant #421). Suggestion 2 → #467 (`status:triage`). Troisième PR mesurée du pilote #458. Les deux prérequis du tag de la v0.17.2, #419 et #421, sont mergés. Aucune migration (v1→v17). (ref #421, PR #465, #467, #458)
- 2026-10-18 : **#419 mergée — `/fix-issue` (contrôle du plan refusé deux fois, chaque fois sur un point réel) → `/pr-review` APPROVE de niveau haut → merge ff par l'API (PR #464, `main` `c859405`) : un `latest.json` vide ou à plusieurs documents ne passe plus la garde d'avant le `DELETE` du registre, et l'étape « Publish » est testée telle quelle.** Le filtre `scripts/check-latest-json.jq` exige exactement un document, appelé avec `-s` par `release.yml` ; défaut reproduit avant le correctif avec le binaire statique officiel de jq 1.6 (celui d'`ubuntu:22.04`) : fichier vide accepté en rc 0, refusé en rc 4 par jq 1.7. `build-latest-json.test.mjs` (28 → 36 tests) extrait le `run:` de l'étape « Publish », identique à l'octet à une lecture PyYAML (46 lignes), et le lance sous `bash -e -o pipefail` avec un `curl` factice en tête du `PATH` ; une garde vérifie que ce texte ne contient aucune expression de workflow, que le runner substituerait même dans un commentaire sans que le test le voie. Refus du plan check : `REVIEW.md` non mis à jour alors que le déclencheur de `check-frontend` changeait, puis une expression de workflow littérale dans un commentaire du `run:`, que le runner aurait évaluée ; troisième passage : pass. **Décision de Max** : `check-frontend` ne saute plus `.claude/**` ni `release.yml`, puisque le test lit `verify-release.sh` et exécute l'étape « Publish » (environ 2,5 min de runner de plus sur ces PR) ; `REVIEW.md`, `CLAUDE.md` et `architecture.md` suivent. Aussi : commentaire périmé de `release.yml:104` (point 3 de #461, commentaire 24939, points 1 et 2 toujours ouverts), ligne `TargetsNotFound` de `tauri dev` sous Linux dans `docs/qa-update-cycle.md`, skill `/release` à jour. Hors dépôt : `la-compagnie-maximus/docs/forgejo-ops.md`, commit `9a8e3f5` (`/actions/tasks` ne lit `limit` qu'avec `page`, remesuré le 2026-10-18 sur 654 tâches ; cas du run 513, que `cancel-in-progress` n'a pas annulé). Preuves : cinq mutations de l'auteur, toutes rouges sous jq 1.6 et 1.7 ; revue de niveau haut (commentaire 24912), six mutations du relecteur toutes rouges, passe sécurité sans constat ; `check-frontend` run 565 vert sous jq 1.6 (134 fichiers, 2256 tests) ; #419 fermée par le merge (commentaire 24941). Deuxième PR mesurée du pilote #458. **Reste à prouver** (suggestion 1 de la revue) : aucune PR ne touchant que `.claude/**` ou `release.yml` n'a encore montré que `check-frontend` se déclenche, la PR #464 touchant aussi `scripts/` ; la première de ce type en fera la preuve. Reste avant le tag de la v0.17.2 : #421. Aucune migration (v1→v17). (ref #419, PR #464, #461, #458)
- 2026-10-18 : **v0.17.2 taggée et publiée (`f42f360`, run 570 vert), sur demande de Max (« /release 0.17.2 »).** Pré-vol sur le tip `e0c0f9e` : build, 2297 vitest, `cargo check`, 267 tests Rust, `.claude/worktrees/` vide. Bump des 5 manifestes, 2 changelogs et de la ligne de `CLAUDE.md`, `Cargo.lock` édité à la main et accepté par `cargo metadata --locked`, garde `windows-sys` rejoué sur le lock édité (9 contrôles, exit 0). `[Unreleased]` portait des Added (la convention donnerait 0.18.0) : question posée, Max a confirmé 0.17.2. Gating changé par #369 (Répartition en Base) : clés Premium des deux testeurs déjà émises, rien à émettre ; le tableau comparatif du site était déjà en avance, commentaire 25050 sur la-compagnie-maximus#180. Tag annoté poussé seul (jamais `--tags`). Étape 9 : `verify-release.sh` en `VERDICT : OK` (7 artefacts, trois clés, extensions, `file:` des signatures, version) ; journal du run : Node `v24.22.0` (#376 prouvé), « Generate latest.json » un paquet par type, garde jq passée, `Delete HTTP 204` puis `Upload HTTP 201` ; endpoint de `tauri.conf.json` en 0.17.2 à trois clés. Restent à Max : étape 10 (cycle réel v0.17.1 → v0.17.2, Linux et Windows, clé Base+), vérifications dans l'app (#421, #369, retours v0.17.1), cycle `.rpm` si une machine est disponible. Aucune migration DB (v1→v17). (ref v0.17.2, #419, #421, #369, #376, #320, la-compagnie-maximus#180)
- 2026-10-18 : **#421 mergée — `/fix-issue` (contrôle du plan passé du premier coup) → `/pr-review` APPROVE de niveau haut → un commit de suivi en tête → merge ff par l'API (PR #465, `main` `ff9656d`) : les confirmations attendent la réponse de l'utilisateur ; issue gardée ouverte (`Refs`, `status:blocked`) jusqu'à la vérification manuelle de Max.** Cause : le script d'initialisation desktop de `tauri-plugin-dialog` 2.6.0 remplace `window.confirm` par une fonction asynchrone, donc chaque garde `if (!confirm(...)) return;` testait une promesse, toujours vraie ; défaut présent dans toutes les versions publiées, le plus grave étant la suppression d'un profil secondaire et de sa base sur « Annuler ». Correctif : `confirmAction()` sur `ask` du plugin, un échec valant refus ; `@tauri-apps/plugin-dialog` ajouté à la version du crate, d'où le niveau haut (dépendance ajoutée). `tsc` ne relève pas `!promise` (mutation M1 verte sous `tsc`), d'où la garde `native-dialog-guard.test.ts`. Preuves : reproduction par six tests rouges de `useLicenseMachines.test.ts` avec une confirmation asynchrone ; `ProfileFormModal.delete.test.ts` sur le harnais `hookHarness` ; mutations de l'auteur rouges à 8 sur 8 ; revue (commentaire 24953) avec 8 mutations du relecteur sur 9 rouges, la survivante étant un alias (`const c = confirmAction`). Suggestion 1 appliquée après la revue (`ff9656d`, tests seuls, non relu, nommé dans le commentaire 25025) : l'alias et trois formes natives (`window["confirm"]`, `confirm?.(`, `const { confirm } = window`) sont désormais rouges. Rebase sur `5222329` (PR #450, mergée entre-temps, `SKILL.md` seul) ; `check-frontend` vert sur `ff9656d`, 2297 tests (2256 avant #421). Suggestion 2 → #467 (`status:triage`). Quatrième PR mesurée du pilote #458. Les deux prérequis du tag de la v0.17.2, #419 et #421, sont mergés. Aucune migration (v1→v17). (ref #421, PR #465, #467, #458)
- 2026-10-18 : **#419 mergée — `/fix-issue` (contrôle du plan refusé deux fois, chaque fois sur un point réel) → `/pr-review` APPROVE de niveau haut → merge ff par l'API (PR #464, `main` `c859405`) : un `latest.json` vide ou à plusieurs documents ne passe plus la garde d'avant le `DELETE` du registre, et l'étape « Publish » est testée telle quelle.** Le filtre `scripts/check-latest-json.jq` exige exactement un document, appelé avec `-s` par `release.yml` ; défaut reproduit avant le correctif avec le binaire statique officiel de jq 1.6 (celui d'`ubuntu:22.04`) : fichier vide accepté en rc 0, refusé en rc 4 par jq 1.7. `build-latest-json.test.mjs` (28 → 36 tests) extrait le `run:` de l'étape « Publish », identique à l'octet à une lecture PyYAML (46 lignes), et le lance sous `bash -e -o pipefail` avec un `curl` factice en tête du `PATH` ; une garde vérifie que ce texte ne contient aucune expression de workflow, que le runner substituerait même dans un commentaire sans que le test le voie. Refus du plan check : `REVIEW.md` non mis à jour alors que le déclencheur de `check-frontend` changeait, puis une expression de workflow littérale dans un commentaire du `run:`, que le runner aurait évaluée ; troisième passage : pass. **Décision de Max** : `check-frontend` ne saute plus `.claude/**` ni `release.yml`, puisque le test lit `verify-release.sh` et exécute l'étape « Publish » (environ 2,5 min de runner de plus sur ces PR) ; `REVIEW.md`, `CLAUDE.md` et `architecture.md` suivent. Aussi : commentaire périmé de `release.yml:104` (point 3 de #461, commentaire 24939, points 1 et 2 toujours ouverts), ligne `TargetsNotFound` de `tauri dev` sous Linux dans `docs/qa-update-cycle.md`, skill `/release` à jour. Hors dépôt : `la-compagnie-maximus/docs/forgejo-ops.md`, commit `9a8e3f5` (`/actions/tasks` ne lit `limit` qu'avec `page`, remesuré le 2026-10-18 sur 654 tâches ; cas du run 513, que `cancel-in-progress` n'a pas annulé). Preuves : cinq mutations de l'auteur, toutes rouges sous jq 1.6 et 1.7 ; revue de niveau haut (commentaire 24912), six mutations du relecteur toutes rouges, passe sécurité sans constat ; `check-frontend` run 565 vert sous jq 1.6 (134 fichiers, 2256 tests) ; #419 fermée par le merge (commentaire 24941). Troisième PR mesurée du pilote #458. **Reste à prouver** (suggestion 1 de la revue) : aucune PR ne touchant que `.claude/**` ou `release.yml` n'a encore montré que `check-frontend` se déclenche, la PR #464 touchant aussi `scripts/` ; la première de ce type en fera la preuve. Reste avant le tag de la v0.17.2 : #421. Aucune migration (v1→v17). (ref #419, PR #464, #461, #458)
- 2026-10-18 : **#455 mergée — `/fix-issue` → `/pr-review` de niveau haut REQUEST_CHANGES, corrigé dans le texte → merge ff par l'API sans second tour (PR #459, `main` `c5efc38`) : `tauri-plugin-updater` compilé sans sa feature `zip`, `audit.yml` de nouveau vert. #457 fermée : les skills de revue lisent `REVIEW.md`.** `zip` 4.6.1, compilé pour Windows seulement par la feature par défaut `zip` de l'updater, n'est corrigé qu'en 9.0.0, hors de portée de `tauri-plugin-updater` 2.14.0 (`zip ^4`) : l'updater déclaré en `default-features = false` avec `rustls-tls` sort `zip`, `arbitrary` et `derive_arbitrary` du lock (666 → 663) et avec eux RUSTSEC-2026-0367 à -0369, sans entrée dans `.cargo/audit.toml` (règle 1 de l'ADR 0018). `tar` quittant le graphe Linux, le canari de la garde des suppressions passe à `webkit2gtk`, conditionnel à Linux comme l'était `tar` (le contrôle du plan a écarté `tauri`, inconditionnel, que proposait l'analyse) ; preuve Windows par `cargo xwin check`, témoin sur `main` (`zip` compilé) puis branche (sans `zip`). Première PR mesurée du pilote #458, de niveau haut (fixé par `src-tauri/Cargo.toml`, `src-tauri/Cargo.lock`, l'étape de verdict de `check-rust.yml` et le skill `/release`) : la revue (commentaire 24757) rejoue le correctif (quatre mutations du canari, `cargo xwin check`, passe sécurité sans constat de §1 à §4) et bloque sur une fausse preuve du corps de la PR : le cycle de mise à jour de la prochaine release part de la v0.17.1, dont l'updater a encore `zip`, il n'exécute donc pas le chemin d'installation sans `zip`. Corrigé sans commit dans le corps de la PR et dans celui de #455 (commentaire 24806) ; **décision de Max** : merger sans second tour. Preuves : rebase sur `main`, les neuf fichiers de la PR identiques à l'octet à la tête relue `85b7ef9` ; `check-rust` run 563 vert sur `c5efc38` (canari `webkit2gtk`, gardes 2/2 et 9/9, 267 tests, audit à 663 crates, lock non réécrit) ; après le merge, `workflow_dispatch` d'`audit.yml` : run 564 vert (cargo-audit 0.22.2, 1338 avis, 663 crates, aucune vulnérabilité, aucun des trois IDs `zip` ; 18 avertissements autorisés, les 12 d'avant et six `unmaintained` parus le 2026-10-18, RUSTSEC-2026-0370 à -0372) ; PR en `Refs #455`, d'où une fermeture à la main (commentaire 24830). #457 (skills globaux, hors git, aucune PR) : `pr-review` lit `REVIEW.md` sur la branche par défaut (Context), calcule le niveau au Step 0bis et l'annonce en première ligne du verdict ; profondeur par niveau (bas = lecture du diff ; haut = mutation obligatoire, passe sécurité bloquante faite dans le fork, car un fork ne lance pas d'agent et `security-scan` n'est défini qu'au niveau du monorepo, APPROVE avec « Max doit lire avant le merge. ») ; savoir propre à simpl-resultat retiré du skill ; `sprint` 4b renvoie à `/pr-review` au lieu d'une copie de checklist (la copie avait perdu la section Tests) ; `DAILY-REPORT` d'`autopilot` avec une section « Max doit lire » et `prs_high_level` ; `fix-issue` 6.5 prend ses commandes dans `REVIEW.md` ; une entrée de CHANGELOG par skill. Preuve : la revue de la PR #459 ouvre sur la ligne de niveau (commentaire 24757) ; fermeture au commentaire 24764. Pilote #458 en `status:in-progress`, relevé ouvert (commentaire 24819), PR 1 = #459. **Acquis** : le cycle réel de mise à jour d'une release exécute l'updater de la version précédente ; seul le `check()` final passe par le nouveau. Suivi #463 (l'étape 10 de `/release` et `docs/qa-update-cycle.md` rattachent le cycle à la release qui livre le changement, alors qu'un changement de l'updater ne se prouve qu'au cycle N → N+1). Aucune migration (v1→v17). (ref #455, PR #459, #457, #458, #463)
- 2026-10-18 : **#456 mergée — `/fix-issue` (contrôle du plan refusé trois fois, chaque fois sur des points réels, derniers points appliqués, poursuite décidée par Max) → deux `/pr-review` APPROVE, le second après application des suggestions du premier → merge ff par l'API (PR #460, `main` `24da72b`) : `REVIEW.md` à la racine.** Calibration sur les PR mergées de #344 à #452 : 3/28/8 sur les 39 PR de référence (20,5 % de niveau haut pour une cible de 20 % ; écart justifié, les huit touchent la licence, les bases de profils et les migrations, ou `release.yml`, qui détient la clé de signature), contre 3/19/17 avec les motifs d'essai du document de départ, et 6/33/12 sur les 51 de la plage. Les « 39 dernières PR » de ce document venaient d'un tri par date de mise à jour (`limit=40&sort=recentupdate`) : liste figée dans la PR. **Décisions de Max** : une montée de version d'un paquet déjà présent dans un lock reste de niveau normal, correctifs d'advisory compris (2026-10-17) ; `db.ts` et `dataExportService.ts` restent normaux même quand le diff touche le verrou ou la restauration (2026-10-18). Preuves : script relancé à neuf contre l'API à chaque changement de règle, niveaux identiques PR par PR ; `--check` rouge sur une copie du tableau privée d'un motif ; CI `check-frontend` 562 verte (134 fichiers, 2248 tests). **Acquis** : l'API Forgejo marque un fichier modifié `changed`, pas `modified` (un test sur `modified` mettait toutes les PR de lock en haut) ; un contrôle de contenu de workflow doit ignorer les commentaires (#375 sortait haute sur le mot « toolchain ») ; les pages de l'API plafonnent à 50 éléments. Suivis : #461 (CSV de `src/__fixtures__/samples/` compilés par `include_str!` hors des `paths` de `check-rust`, `cargo-xwin` et toolchain non épinglés dans `release.yml`, commentaire périmé de `release.yml:104`), #462 (suggestions de la seconde revue, entrées du pilote #458), commentaire sur #457 (lecture sur `main`). Aucune migration (v1→v17). (ref #456, PR #460, #461, #462, #457, #458)
@ -62,26 +65,20 @@ Audit critique de la page Bilan livré (`docs/audit-bilan-2026-05.md`, revue CPA
- 2026-10-15 : **Milestone `planned-2026-10-12-retours-onboarding-v0171` mergée — `/autopilot` (8 workers en série, 1 h 14, worker N+1 lancé pendant la CI du maillon N, CI lue à chaque maillon, runs 543-551) → huit `/pr-review` APPROVE en parallèle (aucun bloquant) → merge ff par l'API, chaque enfant reciblé sur `main` (`main` `934bcbf`, 8 PRs `merged`).** Tip éprouvé en worktree `npm ci` propre : sonde rc=1, build, 2222 vitest (2065 avant), 267 Rust. 31 décisions HIGH, 25 MEDIUM, 0 LOW ; mutations des workers et des relecteurs presque toutes rouges, les survivantes sans effet de comportement ou épinglées. **Acquis** : deux workers sur huit ont perdu leur implémentation non commitée au `git checkout --` de la passe de mutations → consigne « commit avant la première mutation » ajoutée en cours de run, zéro incident ensuite ; les corps de PR des workers ne portent pas `Resolves #N` en clair (seulement les commits), sans effet sur un merge ff. Trou global relevé par deux revues : aucun test ne détecte une clé i18n présente dans une seule langue (#446). Aucune migration (v1→v17). (ref #424, #422, #427, #426, #430, #431, #425, #432, PRs #438-#445, #446)
- 2026-10-13 : **Milestone `planned-2026-10-10-fiabilite-tests` mergée — `/autopilot` (4 workers en série, 1 h 25, CI lue à chaque maillon) → quatre `/pr-review` APPROVE en parallèle → suivis en tête de pile → merge ff par l'API, chaque enfant reciblé sur `main` (`main` `c17bf5d`, 4 PRs `merged`).** Mesure du rattrapage : 306 ms en release pour 100 001 transactions (T490, NVMe), sous la règle des 3 s, donc `STARTUP_TIMEOUT_MS` reste à 10 000 (ADR 0021). Inventaire de #389 : 27 fichiers et non 24, trois mocks bruts venus de #423. Suivis appliqués en tête (`74fae14`, `a1c31a1`, `ac3a981`, `86eff9b`, `c17bf5d`), non relus : `close()` d'un ancien proxy rejeté, échec de fermeture consigné sans bloquer le changement de profil, `withoutFolders` qui ne laisse plus passer un dossier contenant une espace, garde i18n plus stricte, badge traduit. Tip éprouvé en worktree `npm ci` propre : sonde rc=1, tsc, build, 2065 vitest, 262 Rust. ADR 0024 (serveur MCP, Proposed) rebasé sur le merge puis poussé (`977ef3a`). **Acquis** : l'orchestrateur a d'abord contredit à tort un constat juste du worker (badge `best-effort` codé en dur), sur un `grep` tronqué par `head` ; ne jamais conclure à l'absence depuis une sortie tronquée. Aucune migration (v1→v17). (ref #408, #409, #389, #395, PRs #433-#436, #437)
- 2026-10-12 : **#423 mergée (PR #428, `main` `8898213`) — menus déroulants de catégorie avec saisie dans le formulaire de catégorie et le dialogue mot-clé.** Issue créée et analysée le jour même (`/analyze` : types `Category` vs `CategoryTreeNode` incompatibles → type structurel `CategoryLike` sur le combobox ; le formulaire ne connaissait pas l'id édité → prop `editingId` ; deux listes différentes → **D2** de Max : liste des Transactions ; **D1** : #423 porte l'exclusion UI, #393 garde la validation service). Plan check refusé une fois (la liste `absolute` était rognée par le scrollport du dialogue, réglé en sortant les champs du bloc défilant). Première revue **REQUEST_CHANGES** : la règle ne regardait que les enfants directs, une racine avec petits-enfants pouvait recevoir un parent (4ᵉ niveau) ; corrigé par la hauteur du sous-arbre, test rouge d'abord sur la sonde du relecteur. Seconde revue **APPROVE**, quatre suivis appliqués en tête (`8898213`, non relu : commentaires #393 corrigés, garde de cycle épinglée, espions sur `buildParentOptions`, garde redondante retirée). Preuves : 1963 vitest, 9 mutations rouges de l'auteur (une survivante remplacée : la règle « descendance » était impliquée par la règle de profondeur), CI 526-528, worktree `npm ci` propre. **Acquis** : `/commits/<sha>/statuses` renvoie l'historique (`pending` puis `success`), lire `/commits/<sha>/status` agrégé ; `head_commit_id` du merge exige le SHA complet (409 « head out of date » sur un SHA court). Aucune migration (v1→v17). (ref #423, PR #428, #429, #393)
- 2026-10-12 : **Milestone `planned-2026-10-10-release-deps` mergée — `/autopilot` (4 PRs stackées en 1 h 50, CI lue dans les journaux à chaque maillon) → quatre `/pr-review` APPROVE → PR #418 de suivis en tête de pile → `/pr-review` APPROVE → merge ff par l'API, chaque enfant reciblé sur `main` (`main` `9e8c41b`, 5 PRs `merged`).**
- **Décision de Max : clé générique `linux-x86_64` retirée** de `latest.json`. Le worker de #320 puis la revue ont mesuré que ses seuls lecteurs (AppImage v0.4.3 à v0.4.5, binaire hors paquet) ne savaient pas installer le `.deb` qu'elle servait, et que les 64 tags qui embarquent l'updater (plugin 2.10.0) cherchent d'abord la clé de leur paquet : ces lecteurs reçoivent désormais `TargetsNotFound`, rien n'est installé.
- **Suivis des revues dans une 5ᵉ PR (#418)** plutôt qu'en commits sur #417 : le retrait touche la garde d'avant le `DELETE` du registre, catégorie « garde de destruction » de `/merge-stack`, donc relue avant le merge, et les quatre têtes revues n'ont pas bougé. Le contrôle passe dans `scripts/check-latest-json.jq`, exercé à chaque PR par le test du script (11 → 28 tests, 10 mutations rouges, vert sous jq 1.6) ; `/release` rejoue le garde `windows-sys` juste après l'édition de `Cargo.lock`.
- **Constats** : la prémisse « pas de Python dans le conteneur » de #345 était fausse (ADR 0023 corrigé) ; le déclencheur de la dérive `windows-sys` n'est pas « `hyper` et ce qu'il tire » (`f4b09b0`, #310) ; react-router 7.18.3 valide les navigations (150 contrôles sur les cibles de l'app, aucun échec) ; `/actions/tasks` ne liste un job qu'une fois pris par le runner, seuls les statuts de commit voient la file.
- **Restes** : #419, dont le point 1 (sous jq 1.6, le filtre accepte un `latest.json` vide ou à deux documents, inatteignable aujourd'hui) à corriger avant le prochain tag ; vérifications de la prochaine release dans Blockers ; vérification de la navigation dans l'app lancée (Linux, Windows), confirmatoire.
- Aucune migration DB (v1→v17). (ref #376, #345, #320, #358, #317, PRs #414-#418, #419, ADR 0023)
## Blockers actifs
- Aucun blocker externe dur. `spec-monetisation` **fermée 12/12** (2026-07-08) — #50/#52/#53/#135/#136 livrées, ne sont plus des blockers.
- **Vérifications dues à la prochaine release** (v0.17.2, après le tag, étape 9 de `/release` ; prérequis du tag, #419 et #421, tous deux mergés) :
- **Vérifications dues sur la v0.17.2 publiée** (étape 9 de `/release` faite le 2026-10-18 : `verify-release.sh` OK, Node `v24.22.0`, trois clés ; étape 10 faite sous Linux le 2026-10-18, trace dans le corps de la release ; restent les points ci-dessous, à Max) :
- Retours d'onboarding v0.17.1 (#438-#445), dans l'app : cas de la section « Retours de la v0.17.1 » de `docs/qa-onboarding.html` et parcours guidé à huit étapes, en particulier `v0171-import-source-reopen`, `v0171-budget-card-leaves`, l'encadré « Structure attendue » dans les deux thèmes et la première ouverture d'un profil qui avait fini le parcours (#446).
- Répartition réservée à Base (#369), dans l'app : en Gratuite, cadenas sur le bouton Répartition de la page Transactions et écran de déverrouillage au clic, jamais la fenêtre de répartition, lignes déjà réparties toujours marquées de l'icône orange ; en Base, fenêtre de répartition comme avant. Puis dire sur la-compagnie-maximus#180 que le décalage avec le tableau comparatif déployé est résorbé.
- `release.yml` sous Node 24 (#376) : `node --version` à `v24.x` dans le journal du run de release, et `verify-release.sh` vert. Le diff touchant `release.yml`, l'étape 10 de `/release` (cycle réel de mise à jour, `docs/qa-update-cycle.md`) s'applique aussi, selon la règle du skill. Le bump de `rustls` de #447 (dépendance de `tauri-plugin-updater`) la rend obligatoire lui aussi. L'updater compilé sans `zip` (#455) est aussi dans cette release, mais ce cycle part de la v0.17.1, dont l'updater a encore `zip` : il ne prouve rien de l'updater sans `zip` (#463).
- `latest.json` à trois clés (#320, clé générique `linux-x86_64` retirée le 2026-10-11) : étape « Generate latest.json » du journal lue (un paquet retenu par type), `verify-release.sh` en `VERDICT : OK` sur `linux-x86_64-deb`, `linux-x86_64-rpm` et `windows-x86_64` (extensions, `file:` des signatures). Cycle réel depuis une installation `.rpm` (§3 de `docs/qa-update-cycle.md`) dès qu'une machine Fedora ou openSUSE est disponible, sinon « non déroulé » avec la raison dans la trace de la release.
- Confirmations de #421, dans l'app : supprimer un profil secondaire, « Annuler » → profil et fichier `.db` intacts, « Confirmer » → les deux supprimés ; libellés des boutons en français et en anglais ; observer la saisie du NIP (`prompt()`) ; un autre site de confirmation (catégorie, ajustement, modèle de budget, catégorie du Bilan ou retrait de la clé) ; sous Windows si possible. Puis fermer #421 à la main (PR en `Refs`).
- **Vérifications dues à la release suivante** (celle d'après le prochain tag) : cycle réel de mise à jour Windows depuis la première version qui embarque #455 (et #447), première exécution de l'installation par l'updater sans `zip` et du téléchargement par `rustls` 0.23.46 ; dû même si cette release ne touche pas l'updater (#463).
- Répartition réservée à Base (#369), dans l'app : en Gratuite, cadenas sur le bouton Répartition de la page Transactions et écran de déverrouillage au clic, jamais la fenêtre de répartition, lignes déjà réparties toujours marquées de l'icône orange ; en Base, fenêtre de répartition comme avant. Commentaire posé sur la-compagnie-maximus#180 à la publication (25050).
- `release.yml` sous Node 24 (#376) : **fait** (`v24.22.0`, run 570). Le diff touchant `release.yml`, l'étape 10 de `/release` (cycle réel de mise à jour, `docs/qa-update-cycle.md`) s'applique aussi, selon la règle du skill : **faite sous Linux** (`.deb`, v0.17.1 → v0.17.2, Max, 2026-10-18 ; invite de mot de passe vue, type non consigné), **reste Windows**. Le bump de `rustls` de #447 (dépendance de `tauri-plugin-updater`) la rend obligatoire lui aussi. L'updater compilé sans `zip` (#455) est aussi dans cette release, mais ce cycle part de la v0.17.1, dont l'updater a encore `zip` : il ne prouve rien de l'updater sans `zip` (#463).
- `latest.json` à trois clés (#320, clé générique `linux-x86_64` retirée le 2026-10-11) : **fait** (journal et `verify-release.sh`, run 570). Cycle réel depuis une installation `.rpm` (§3 de `docs/qa-update-cycle.md`) dès qu'une machine Fedora ou openSUSE est disponible, sinon « non déroulé » avec la raison dans la trace de la release.
- Confirmations de #421 : **fait** (Max, sous Linux, 2026-10-18, concluant ; Windows non déroulé) ; #421 fermée à la main le même jour (commentaire 25074).
- **Vérifications dues à la release suivante** (celle d'après la v0.17.2) : cycle réel de mise à jour Windows depuis la première version qui embarque #455 (et #447), première exécution de l'installation par l'updater sans `zip` et du téléchargement par `rustls` 0.23.46 ; dû même si cette release ne touche pas l'updater (#463).
- **Le paiement est live : « aucun tag avant le go-live » n'a plus de raison d'être, et la release desktop qu'attendait le go-live est publiée (v0.16.0, 2026-10-03).** Bascule live le 2026-09-29 (Product et Price live à 19 $ CAD, webhook, variables Stripe de production, redeploy `3673d09` de maximus-api, URL `cs_live_` vérifiée), puis achat réel de contrôle le 2026-09-30 : clé sur `/merci` et par courriel, activation dans l'app, remboursement complet et licence révoquée par `charge.refunded`. **Volet serveur clos le 2026-10-03** (derniers commentaires relus le 2026-10-04) : maximus-api#62 fermée, tous critères cochés (maximus-api 0.4.2 en prod, secrets en runtime seul), avec la milestone `spec-paiements` de maximus-api (12/12) ; la-compagnie-maximus#150 (Link dans les textes légaux) livrée et fermée le 2026-10-01. **Go-live clos : la-compagnie-maximus#141** fermée le 2026-10-10 sur décision de Max, l'updater vérifié (Free refuse et invite à acheter, Base accepte ; confirmé le même jour). Restent pour mémoire, sans issue : le Dashboard Stripe (logo, paramètres Checkout, reçus automatiques, alertes d'échec de webhook) et les relevés du commentaire de fermeture. la-compagnie-maximus#184 (politique de confidentialité : données d'activation, contrôle au démarrage) est en `status:review` ; sa PR reste en brouillon jusqu'au déploiement de maximus-api#85 (commentaire du 2026-10-03). Les deux textes des suites de licence (contrôle à la saisie, retrait de la clé) y sont postés depuis le 2026-10-05 (commentaire 19724). **Vérifications manuelles sur la release publiée, toutes faites** : #365 le 2026-10-03, #346 et #350 le 2026-10-04 (voir Décisions). L'étape 10 sous Windows est faite (Michel, confirmée le 2026-10-10).
- Backlog ouvert : **vague `planned-2026-09-24-paiements` close 3/3** (milestone fermée le 2026-09-30) : #270 (PR #359) et #346 (PR #362) mergées le 2026-09-27, #347 (PR #364, ferme aussi #360) mergée le 2026-09-30 ; volet site **clos** (maximus/la-compagnie-maximus#153, redirection de `/simpl-resultat` en prod). **#365 fermée le 2026-10-03** après sa vérification manuelle. **Milestone `planned-2026-10-03-suites-licence` fermée 3/3 le 2026-10-05** (#373, #370, #367 mergées, voir Décisions ; suivi #389 en `status:triage`). Hors milestone : **#369** (réserver le fractionnement de transactions à l'édition Base) **fermée le 2026-10-17** (PR #452, voir Décisions) ; **#372** (la liste complète des versions repousse le Journal en bas de Paramètres → Systèmes) reste en `status:ready`. **#350 fermée le 2026-10-04** (étape 3 vérifiée en production, voir Décisions) ; #363 fermée le 2026-10-10 sur décision de Max (ses tests, absorbés par #347, sont livrés dans la v0.16.0) ; réglés côté serveur et site : maximus-api#63 (clés de 100 ans) et maximus-api#70 (réactivation d'une machine désactivée), fermées et contenues dans `3673d09`, le commit déployé à la bascule du 2026-09-29, et la-compagnie-maximus#157, fermée, dont les CGV sont publiées en tronc commun plus annexe Simpl-Résultat (annexe relue en production le 2026-09-30, plus aucune durée de 10 ans) ; côté serveur, `/v1/prices` ne vérifie pas qu'une machine est encore active (une machine désactivée garde les cours jusqu'à l'expiration de son jeton), issue maximus-api à ouvrir ; suites de #350 ouvertes le 2026-10-01 : maximus-api#82 (`status:triage` : identifiants machine bruts déjà stockés, lignes désactivées comprises ; à rehacher avant l'expiration des premiers jetons bruts, sinon une réactivation crée une seconde ligne) et la-compagnie-maximus#184 (`status:review`, voir ci-dessus) ; go-live clos (la-compagnie-maximus#141 fermée le 2026-10-10, maximus-api#62 le 2026-10-03) ; `spec-paiements` fermée ici 5/5 ; onboarding phase 2 (parcours guidé) **mergée** : milestone `planned-2026-10-06-onboarding-parcours-guide` fermée 6/6 le 2026-10-08 (#396 à #401, `ee17f31`), suivis **#408** et **#409** (`status:triage`) ; onboarding phase 1 **livrée** : milestone `planned-2026-10-03-onboarding-phase1` fermée 7/7 le 2026-10-04 (#351 à #357, mergées en avance rapide, `667e058`) ; suivis ouverts : **#384** (`status:ready`, suivis non bloquants des revues) et **#371** (`status:blocked`, hors `/autopilot` : en-têtes CSV BMO à fournir par Max depuis un compte réel, un par type de compte, chèques/épargne et Mastercard, avec des valeurs fictives) ; analyse d'origine dans `docs/analyse-onboarding-2026-09.md`, plan détaillé dans les `spec-*-onboarding-phase1.md` locaux, ignorés par git ; #271 absorbé par #301, livré ; `spec-ci-build-optimization` **fermée 4/4** le 2026-10-05 (#232 livrée le 2026-07-27 ; #234 close le 2026-10-05 avec ses quatre preuves : dispatch run 464, PR #386 run 480, run planifié 488, `actcache` à 999 Mo) ; **#376** fermée le 2026-10-12 (Node 24, PR #414). Le suivi « glob `src-tauri/**` non prouvé » ouvert avec #232 est **levé** : la PR #344 est le cas test isolé attendu (`Cargo.lock` + 2 `.md` seulement) — `check-rust` a bien tourné, `check-frontend` a bien été sauté par sa denylist.
- Suivis des advisories : **#312, #313 et #315 fermées le 2026-08-15** (PRs #321/#322 mergées). **#314 fermée le 2026-08-15, prémisse infirmée** — elle affirmait « zéro run `schedule` », or `audit.yml` tire tous les jours à 06:00 UTC (**19 runs `schedule` verts** du 07-28 au 08-15, sans trou) ; elle a été écrite le 07-27 vers 23:56Z, ~6 h avant le premier tir programmé possible, et décrivait donc une fenêtre trop courte, pas un scheduler en panne. Ces 19 runs confirment au passage que `.cargo/audit.toml` est bien lu en conteneur **sur `main`** — l'ADR 0018 ne l'avait vérifié que par un `workflow_dispatch` sur une branche. **#343 fermée le 2026-09-04** (PR #344) — RUSTSEC-2026-0258 sur `h2`, la seule vulnérabilité qui rougissait l'audit depuis le 08-19 ; l'audit est de nouveau vert sur `main`, prouvé par `workflow_dispatch` (run 393) et non déduit du run de PR. **#348 fermée le 2026-09-21** (PR #349) — RUSTSEC-2026-0285 sur `rustls`, seule vulnérabilité rougissant l'audit depuis le 09-15 (7 runs, 405→411) ; vert reprouvé par `workflow_dispatch` sur `main` (run 414 : 666 paquets, zéro vulnérabilité, 12 warnings autorisés). Deux advisories en cinq semaines sur le même chemin, celui de la mise à jour automatique. **#447 fermée le 2026-10-16** (PR #448, run 556 vert), quatre avis `rustls` sur ce même chemin ; le Défenseur n'audite pas le Rust (agent-defenseurs#186), `audit.yml` reste le seul canal pour les avis RustSec. **#455 fermée le 2026-10-18** (PR #459, run 564 vert), trois avis `zip` sur ce même chemin, retirés avec la feature `zip` de l'updater plutôt que supprimés. **#317** fermée le 2026-10-12 par la PR #417 (#358). Reste **#319** (déclencheur de retrait pour `rsa`, désormais **seule** entrée de `.cargo/audit.toml` — le garde-fou est passé à 2 vérifications). **#345** fermée le 2026-10-12 (PR #415) : garde `Verify windows-sys pinning` dans `check-rust.yml` et ADR 0023, qui portent la mesure, le coût (3 contre 5 versions compilées pour Windows) et la condition de sortie. Côté npm, **#358** fermée le 2026-10-12 (PR #417) : lock régénéré par `npm@11.21.0` dans les bornes de `package.json`, `npm audit` 8 → 0 au 2026-10-10.
- **#320** fermée le 2026-10-12 (PR #416, clé générique retirée par la PR #418) : une clé `latest.json` par paquet Linux, à vérifier au prochain tag (puce « Vérifications dues à la prochaine release ») ; le §3 de `docs/qa-update-cycle.md` est devenu la procédure de test rpm.
- **#320** fermée le 2026-10-12 (PR #416, clé générique retirée par la PR #418) : une clé `latest.json` par paquet Linux, vérifiée sur la v0.17.2 publiée (run 570, `verify-release.sh`) ; cycle `.rpm` encore dû (puce « Vérifications dues sur la v0.17.2 publiée ») ; le §3 de `docs/qa-update-cycle.md` est devenu la procédure de test rpm.
- Suivis ouverts du chantier import (milestone fermée) : le refus du format « montant absolu + indicateur D/C » ne scanne que `amountCol ± 1`, donc une colonne D/C placée ailleurs passe encore ; dérives de comptes préexistantes dans `CLAUDE.md` et `docs/architecture.md` (composants, pages, services, `Version actuelle : 0.6.3` vs tag v0.14.0) mesurées et documentées en revue, non corrigées.
- **Étape 10 de la release v0.15.0 consignée le 2026-09-13** — plus un blocker : cycle réel v0.14.0 → v0.15.0 validé par les deux testeurs ; trace rédigée pour le corps de la release (`PATCH` à appliquer par Max) ; invite d'authentification Linux non consignée ; #320 reste ouverte (`.rpm`). Deux restes : (1) le texte de la carte Compte Maximus (« Le compte est requis uniquement pour les fonctionnalités Premium », hérité de v0.7) contredit v0.15.0 où Premium vient de la clé, et a vraisemblablement conduit un testeur à se connecter pour rien (code de vérification Logto reçu par courriel) — reformulation livrée par #346 (PR #362), avec une réserve notée dans l'ADR 0017 (exacte tant que le chemin abonnement → Premium reste dormant) ; (2) le flux Logto exact (connexion par code, mot de passe oublié ou inscription) reste à lire dans le journal d'audit. Position produit : v0.17.1 (2026-10-08) ; `[Unreleased]` non vide (Added, Changed, Fixed, Security), en attente du prochain tag.
- **Étape 10 de la release v0.15.0 consignée le 2026-09-13** — plus un blocker : cycle réel v0.14.0 → v0.15.0 validé par les deux testeurs ; trace rédigée pour le corps de la release (`PATCH` à appliquer par Max) ; invite d'authentification Linux non consignée ; #320 reste ouverte (`.rpm`). Deux restes : (1) le texte de la carte Compte Maximus (« Le compte est requis uniquement pour les fonctionnalités Premium », hérité de v0.7) contredit v0.15.0 où Premium vient de la clé, et a vraisemblablement conduit un testeur à se connecter pour rien (code de vérification Logto reçu par courriel) — reformulation livrée par #346 (PR #362), avec une réserve notée dans l'ADR 0017 (exacte tant que le chemin abonnement → Premium reste dormant) ; (2) le flux Logto exact (connexion par code, mot de passe oublié ou inscription) reste à lire dans le journal d'audit. Position produit : v0.17.2 (2026-10-18) ; `[Unreleased]` vide.