state: sync after #369

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
le king fu 2026-10-17 07:46:13 -04:00
parent a8c3fd6997
commit 589aee0b38

View file

@ -1,8 +1,8 @@
# STATE — Simpl'Résultat # STATE — Simpl'Résultat
> Derniere MAJ : 2026-10-16 (**#447 mergée et fermée — `rustls` 0.23.45 → 0.23.46, PR #448 en avance rapide par l'API, `main` `1763a9f`.** RUSTSEC-2026-0346 à -0349, non atteignables, rougissaient `audit.yml` depuis le 2026-10-15 ; vert de nouveau sur `main` (run 556). Pas de release corrective, le cycle réel de mise à jour est dû au prochain tag. Suivis #449 et agent-defenseurs#186. Aucune migration (v1→v17).) > Derniere MAJ : 2026-10-17 (**#369 mergée et fermée — la Répartition réservée à l'édition Base, PR #452 en avance rapide par l'API, `main` `a8c3fd6`.** En Gratuite, le bouton de la page Transactions porte un cadenas et ouvre l'écran de déverrouillage, jamais la fenêtre de répartition ; les répartitions existantes restent comptées. Suivis #451 et #454. **`audit.yml` rouge depuis le 2026-10-17 (run 558)** : trois avis sur `zip` 4.6.1, tiré pour Windows seulement par `tauri-plugin-updater`, à trancher avant le prochain tag. Aucune migration (v1→v17).)
> >
> Précédente MAJ : 2026-10-15 (**Milestone `planned-2026-10-12-retours-onboarding-v0171` mergée, 8/8 fermée — pile #438 → #445 en avance rapide par l'API, `main` `934bcbf`.** Grille Budget en profondeur (#424), import par sous-dossier de compte, fichiers à la racine signalés, nom de source = sous-dossier (#422, #427, #426), cartes Transactions/Budget (#430), aide périmée (#431), étapes de visite et « J'ai compris » (#425), cartes Catégories et Rapports (#432). Suivi #446. Aucune migration (v1→v17).) > Précédente MAJ : 2026-10-16 (**#447 mergée et fermée — `rustls` 0.23.45 → 0.23.46, PR #448 en avance rapide par l'API, `main` `1763a9f`.** RUSTSEC-2026-0346 à -0349, non atteignables, rougissaient `audit.yml` depuis le 2026-10-15 ; vert de nouveau sur `main` (run 556). Pas de release corrective, le cycle réel de mise à jour est dû au prochain tag. Suivis #449 et agent-defenseurs#186. Aucune migration (v1→v17).)
## Position actuelle ## Position actuelle
@ -40,8 +40,11 @@ Audit critique de la page Bilan livré (`docs/audit-bilan-2026-05.md`, revue CPA
**#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`, 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).
**#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).
## Decisions recentes ## Decisions recentes
- 2026-10-17 : **#369 mergée — `/fix-issue` (plan check refusé une fois) → `/pr-review` APPROVE → deux commits de suivi en tête → merge ff par l'API (PR #452, `main` `a8c3fd6`) : la Répartition réservée à l'édition Base.** L'écran de déverrouillage la rangeait déjà en Base (`upsell.features.adjustments`) alors que l'app la laissait ouverte en Gratuite ; désormais, en Gratuite, le bouton garde sa place, porte un cadenas et ouvre l'écran verrouillé (`UpsellDialog`) pour toute ligne, jamais la fenêtre de répartition ; bouton inactif tant que la licence n'est pas `ready` ; répartitions existantes comptées, icône orange gardée. `splitAccessFor` est plus strict que `profileGate` (`allowed` ne court-circuite pas `ready`) ; `TransactionTable` ne rend pas la fenêtre de répartition en `locked` mais la garde pendant un rafraîchissement de licence, et ne rend pas l'incitation en `open`. Refus du plan check (MAJOR) : le câblage de `TransactionTable` n'était pas testé, d'où `TransactionTable.wiring.test.ts` sur le harnais `hookHarness` de #409 ; second passage : pass. Preuves : 21 mutations de l'auteur, toutes rouges ; revue (commentaire 24129) avec 14 des 15 mutations du relecteur rouges, la survivante R14 (un clic verrouillé qui ouvrirait aussi la fenêtre de répartition) épinglée par `d5d0e89` ; `a8c3fd6` réunit la clé de la Répartition dans `SPLIT_FEATURE` ; ces deux commits en tête, non relus, sont nommés dans le commentaire 24148 ; tip en worktree `npm ci` propre (sonde rc=1, build, 2248 vitest sur 134 fichiers, contre 2222) ; CI 557 et 559 ; #369 fermée par le merge. Site : le tableau comparatif de la-compagnie-maximus#180 (PR #298 de ce dépôt-là), en production depuis le 2026-10-16, range déjà la Répartition en Base, en avance sur l'app, décalage accepté par Max ; commentaire 24164 posé le 2026-10-17 (mergé, publié avec la prochaine release, pas encore disponible). Suivis : #451 (incitation de `ProfileSwitcher` sur `UpsellDialog`, Échap, focus) et #454 (`type:bug`, compensation d'une transaction répartie laissée dans l'ancienne catégorie au reclassement, car `updateTransactionCategory` ne touche que le parent ; rare, mais irréparable en Gratuite depuis #369). Aucune migration (v1→v17). (ref #369, PR #452, #451, #454, la-compagnie-maximus#180)
- 2026-10-16 : **#447 mergée — `/fix-issue` (plan check refusé une fois) → `/pr-review` APPROVE → merge ff par l'API (PR #448, `main` `1763a9f`) : `rustls` 0.23.45 → 0.23.46, corrigeant RUSTSEC-2026-0346 à -0349.** Publiés le 2026-10-14, les quatre avis rougissaient `audit.yml` (runs 553 et 555) sans que le lock ait bougé depuis la v0.17.1 ; repérés par la Phase 5.6 du `/warmup` le 2026-10-15, pas par le Défenseur, dont le check `deps` ne lance jamais `cargo audit` (**décision de Max** le 2026-10-15 : sous-check `cargo-audit`, agent-defenseurs#186). Aucun n'est atteignable (`rustls` atteint par `tauri-plugin-updater` → `reqwest` 0.13 seulement ; fournisseur `ring` sans groupe post-quantique, `brotli` non compilée, ni ECH ni `ClientSessionStore` maison), mais la règle 1 de `.cargo/audit.toml` dit corriger, pas supprimer. Diff : deux lignes de `Cargo.lock`, aucun bump compagnon, aucune arête `windows-sys` déplacée, une puce Sécurité par CHANGELOG. Refus du plan check (MAJOR) : « No behaviour change » avait déjà été recadré par `9abf474` au bump précédent, et la 0.23.46 apporte une dizaine d'autres corrections de la couche TLS (21 fichiers de `src/` en amont), donc l'entrée restreint « aucun changement » au code de l'application ; second passage : pass. Preuves : `cargo-audit` 0.22.2 (binaire de la CI) rouge sur l'arbre intact (4 IDs) puis vert ; `check-rust` run 554 lu ligne à ligne (gardes 2/2 et 9/9, 267 tests, 0 vulnérabilité ; à froid, rustc 1.99.1 du 2026-10-13 ayant changé la clé du cache) ; revue (commentaire 23853) avec mutation inverse rouge sur les quatre IDs ; tip en worktree propre (`npm ci`, sonde rc=1, build, 2222 vitest, `cargo test --locked` à 267, gardes, audit exit 0) ; après le merge, `audit.yml` en `workflow_dispatch` sur `main` : run 556 vert (666 crates, 12 warnings autorisés, 0 vulnérabilité). PR en `Refs #447` (critère post-merge), d'où une fermeture à la main (commentaire 23894). Pas de release corrective (décision de Max) : le bump part avec le prochain tag, cycle réel de mise à jour compris. **Acquis** : `cargo-audit` écrit « 1 vulnerability found! » mais « N vulnerabilities found! », chercher `vulnerabilit(y|ies) found` ou `error: [0-9]+ vulnerabilit` ; le journal de `check-rust` porte des codes ANSI (`CARGO_TERM_COLOR=always`) à retirer avant tout `grep`. Suivi #449 (`--locked` absent de `check-rust.yml` et de `release.yml`). Aucune migration (v1→v17). (ref #447, PR #448, #449, agent-defenseurs#186) - 2026-10-16 : **#447 mergée — `/fix-issue` (plan check refusé une fois) → `/pr-review` APPROVE → merge ff par l'API (PR #448, `main` `1763a9f`) : `rustls` 0.23.45 → 0.23.46, corrigeant RUSTSEC-2026-0346 à -0349.** Publiés le 2026-10-14, les quatre avis rougissaient `audit.yml` (runs 553 et 555) sans que le lock ait bougé depuis la v0.17.1 ; repérés par la Phase 5.6 du `/warmup` le 2026-10-15, pas par le Défenseur, dont le check `deps` ne lance jamais `cargo audit` (**décision de Max** le 2026-10-15 : sous-check `cargo-audit`, agent-defenseurs#186). Aucun n'est atteignable (`rustls` atteint par `tauri-plugin-updater` → `reqwest` 0.13 seulement ; fournisseur `ring` sans groupe post-quantique, `brotli` non compilée, ni ECH ni `ClientSessionStore` maison), mais la règle 1 de `.cargo/audit.toml` dit corriger, pas supprimer. Diff : deux lignes de `Cargo.lock`, aucun bump compagnon, aucune arête `windows-sys` déplacée, une puce Sécurité par CHANGELOG. Refus du plan check (MAJOR) : « No behaviour change » avait déjà été recadré par `9abf474` au bump précédent, et la 0.23.46 apporte une dizaine d'autres corrections de la couche TLS (21 fichiers de `src/` en amont), donc l'entrée restreint « aucun changement » au code de l'application ; second passage : pass. Preuves : `cargo-audit` 0.22.2 (binaire de la CI) rouge sur l'arbre intact (4 IDs) puis vert ; `check-rust` run 554 lu ligne à ligne (gardes 2/2 et 9/9, 267 tests, 0 vulnérabilité ; à froid, rustc 1.99.1 du 2026-10-13 ayant changé la clé du cache) ; revue (commentaire 23853) avec mutation inverse rouge sur les quatre IDs ; tip en worktree propre (`npm ci`, sonde rc=1, build, 2222 vitest, `cargo test --locked` à 267, gardes, audit exit 0) ; après le merge, `audit.yml` en `workflow_dispatch` sur `main` : run 556 vert (666 crates, 12 warnings autorisés, 0 vulnérabilité). PR en `Refs #447` (critère post-merge), d'où une fermeture à la main (commentaire 23894). Pas de release corrective (décision de Max) : le bump part avec le prochain tag, cycle réel de mise à jour compris. **Acquis** : `cargo-audit` écrit « 1 vulnerability found! » mais « N vulnerabilities found! », chercher `vulnerabilit(y|ies) found` ou `error: [0-9]+ vulnerabilit` ; le journal de `check-rust` porte des codes ANSI (`CARGO_TERM_COLOR=always`) à retirer avant tout `grep`. Suivi #449 (`--locked` absent de `check-rust.yml` et de `release.yml`). Aucune migration (v1→v17). (ref #447, PR #448, #449, agent-defenseurs#186)
- 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-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-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)
@ -84,17 +87,18 @@ Audit critique de la page Bilan livré (`docs/audit-bilan-2026-05.md`, revue CPA
- **Suite** : #390 reste ouverte en `status:blocked` jusqu'à la liste post-merge. - **Suite** : #390 reste ouverte en `status:blocked` jusqu'à la liste post-merge.
- Aucune migration ajoutée (v1→v17). (ref #390, PR #394, #395, ADR 0021) - Aucune migration ajoutée (v1→v17). (ref #390, PR #394, #395, ADR 0021)
- 2026-10-05 : **v0.17.0 taggée et publiée (`07255e1`, run 491 vert) ; #234 close ; textes de la-compagnie-maximus#184 postés.** Pré-vol du skill sur le tip `8f964e0` : build, 1498 vitest, `cargo check` sans avertissement, 224 Rust ; `.claude/worktrees/` vide. Avant le bump, diff vide depuis `v0.16.0` sur `Cargo.lock`, `Cargo.toml`, `release.yml`, `tauri.conf.json` et `package*.json`, et aucune ligne du diff ne touche le gating par édition : ni clés testeurs à émettre, ni cycle de mise à jour réel exigé (étape 10), la raison étant écrite dans le corps de la release plutôt que tue. Version mineure (fonctionnalités ajoutées) : 5 manifestes, 2 changelogs et la ligne de `CLAUDE.md`, `Cargo.lock` édité à la main et accepté par `cargo metadata --locked`. Tag annoté confirmé par Max, poussé seul (jamais `--tags`). Run 491 en 22 min ; `verify-release.sh` vert (7 artefacts, signatures et URL en 0.17.0) ; l'endpoint de `tauri.conf.json` (registre de paquets) sert aussi la 0.17.0. Le même jour : **#234 fermée** sur sa quatrième preuve (`actcache` à 999 Mo, une seule entrée : celle, isolée, de la PR #375 a été évincée par le ménage par clé), avec la milestone `spec-ci-build-optimization` (4/4) ; la-compagnie-maximus#184 reçoit les deux textes des suites de licence (contrôle à la saisie, retrait de la clé), rattachés aux deux passages de son corps que la v0.17.0 rend faux. Aucune migration DB (v1→v17). (ref v0.17.0, #234, #373, #370, #367, la-compagnie-maximus#184) - 2026-10-05 : **v0.17.0 taggée et publiée (`07255e1`, run 491 vert) ; #234 close ; textes de la-compagnie-maximus#184 postés.** Pré-vol du skill sur le tip `8f964e0` : build, 1498 vitest, `cargo check` sans avertissement, 224 Rust ; `.claude/worktrees/` vide. Avant le bump, diff vide depuis `v0.16.0` sur `Cargo.lock`, `Cargo.toml`, `release.yml`, `tauri.conf.json` et `package*.json`, et aucune ligne du diff ne touche le gating par édition : ni clés testeurs à émettre, ni cycle de mise à jour réel exigé (étape 10), la raison étant écrite dans le corps de la release plutôt que tue. Version mineure (fonctionnalités ajoutées) : 5 manifestes, 2 changelogs et la ligne de `CLAUDE.md`, `Cargo.lock` édité à la main et accepté par `cargo metadata --locked`. Tag annoté confirmé par Max, poussé seul (jamais `--tags`). Run 491 en 22 min ; `verify-release.sh` vert (7 artefacts, signatures et URL en 0.17.0) ; l'endpoint de `tauri.conf.json` (registre de paquets) sert aussi la 0.17.0. Le même jour : **#234 fermée** sur sa quatrième preuve (`actcache` à 999 Mo, une seule entrée : celle, isolée, de la PR #375 a été évincée par le ménage par clé), avec la milestone `spec-ci-build-optimization` (4/4) ; la-compagnie-maximus#184 reçoit les deux textes des suites de licence (contrôle à la saisie, retrait de la clé), rattachés aux deux passages de son corps que la v0.17.0 rend faux. Aucune migration DB (v1→v17). (ref v0.17.0, #234, #373, #370, #367, la-compagnie-maximus#184)
- 2026-10-05 : **Suites de licence livrées — `/autopilot` (2026-10-04, 3 workers séquentiels de 36, 39 et 41 min, CI attendue verte entre deux maillons) → trois `/pr-review` APPROVE → suivis en tête de pile → merge ff par l'API (`main` `2cbc886`).** #373 : contrôle de révocation à la saisie, en arrière-plan, sous un verrou `tauri::async_runtime::Mutex` qui sérialise lecture de l'état → tentative → requête → verdict ; écart accepté : le test de concurrence rougit sans verrou sur le verdict lu par le second contrôle, pas sur le nombre de requêtes (une sonde à deux fils de 200 rondes n'a jamais ouvert la fenêtre). #370 : `remove_license` (clé supprimée d'abord, puis le jeton ; `license.check` gardé ; libération préalable par `deactivate_idempotent` + `note_revocation`, jamais `deactivate_in`, qui supprimerait le jeton avant la clé). #367 : suppression du jeton seulement s'il est « inchangé depuis la requête » (CWE-367), sur un 403 `license_revoked` des cours et à la lecture d'une liste complète sans ligne de ce poste ; garde étendue à la liste par le worker ; lignes de Journal à code fixe. Revues : aucun bloquant ; les 5 mutations survivantes des relecteurs (relais de « déjà révoquée », deux `t` oubliés, `Storage` de `store_license_in`, jeton non UTF-8) et deux autres suggestions (rechargement après un retrait en échec, budget de 6 requêtes) appliquées dans `2cbc886`, prouvées par 2, 18, 4, 1, 10, 1 et 1 tests rouges. Tip validé en worktree `npm ci` propre (sonde rouge rc=1, build, 1498 vitest, 224 cargo), CI 489/490. **Acquis** : appliquer les suggestions de revue en tête de pile garde les têtes revues intactes, donc le merge ff épinglé reste possible maillon par maillon ; un faux `t` qui rend la clé brute rend invisible tout `t` oublié (suite : #389). Aucune migration DB (v1→v17). (ref #373, #370, #367, PRs #386-#388, #389)
## Blockers actifs ## 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. - 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.
- **`audit.yml` rouge depuis le 2026-10-17 06:00 UTC, à trancher avant le prochain tag** (run 558 sur `065f580`, base d'avis passée de 1329 à 1334) : trois avis sur `zip` 4.6.1, à l'extraction d'une archive (liens symboliques, bits SUID/SGID), RUSTSEC-2026-0367 (élevée, 7.3), RUSTSEC-2026-0368 et RUSTSEC-2026-0369 (critique, 9.1). `zip` n'est compilé que pour Windows, tiré par `tauri-plugin-updater` 2.10.0 via sa feature par défaut `zip` (qui active aussi `tar` et `flate2`) ; il n'est corrigé qu'en `zip` >= 9.0.0, aucun 4.x corrigé, et `tauri-plugin-updater` 2.14.0 exige toujours `zip ^4`. L'extraction n'a lieu que sur un paquet zip dont la signature a été vérifiée (`download` vérifie avant `install`), et nos paquets Windows sont des `.exe` NSIS. Piste : déclarer l'updater sans ses features par défaut en gardant `rustls-tls`, ce qui retirerait `zip` (et `tar`, canari de la garde des suppressions de `check-rust`, à remplacer). Issue à ouvrir sur décision de Max. #447 reste fermée à bon droit : ses quatre identifiants n'apparaissent plus dans le run 558.
- **Avant le prochain tag : #419, point 1.** Sous jq 1.6, la version du conteneur de release, `scripts/check-latest-json.jq` accepte un `latest.json` vide ou à deux documents : c'est la garde du `DELETE` du registre. Inatteignable aujourd'hui (la génération échoue fermée avant « Publish »), mais à fermer avant de tagger. - **Avant le prochain tag : #419, point 1.** Sous jq 1.6, la version du conteneur de release, `scripts/check-latest-json.jq` accepte un `latest.json` vide ou à deux documents : c'est la garde du `DELETE` du registre. Inatteignable aujourd'hui (la génération échoue fermée avant « Publish »), mais à fermer avant de tagger.
- **Vérifications dues à la prochaine release** (après le tag, étape 9 de `/release`) : - **Vérifications dues à la prochaine release** (après le tag, étape 9 de `/release`) :
- 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). - 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. - `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.
- `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. - `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.
- **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). - **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, en `status:ready` : **#369** (réserver le fractionnement de transactions à l'édition Base) et **#372** (la liste complète des versions repousse le Journal en bas de Paramètres → Systèmes). **#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. - 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. **#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. - 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. **#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é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.
- 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. - 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.