The autopilot stack of 2026-10-04 is merged fast-forward through the API, main at2cbc886, milestone planned-2026-10-03-suites-licence closed 3/3. The seven review suggestions were applied on the stack head (2cbc886), each proven by a red mutation. Record the decision, the manual checks due with v0.17.0 (ordered so the activation token is destroyed last), #234 points 2 and 3 done, and the #389 follow-up. Rotate out the 2026-09-24 decision to keep ten. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
2cbc886653
commit
8f964e096b
1 changed files with 10 additions and 7 deletions
17
STATE.md
17
STATE.md
|
|
@ -1,8 +1,8 @@
|
|||
# STATE — Simpl'Résultat
|
||||
|
||||
> Derniere MAJ : 2026-10-04 (**#350 fermée sur l'étape 3 et #346 vérifiée en production, après un resync des Blockers.** Le `/warmup` a vu que la vérification de #365 avait dû effacer le jeton de la v0.15.0 du poste Linux ; un script local en lecture seule l'a confirmé, puis la clé testeur ressaisie et « Activer » ont donné un jeton dérivé (`64 brut: False dérivé: True`). Avant de ressaisir la clé, en Gratuite par la clé révoquée, Max a vérifié #346 : la PR de #370 portera `Fixes`. Plus tôt, resync des Blockers que la synchro `8c55e26` avait laissés au 2026-10-03 (onboarding à 0/7, #365, #367/#370, maximus-api#62, la-compagnie-maximus#150, #317, `[Unreleased]`). Audit quotidien vert (run 475) ; premier tir planifié de `check-rust` le lundi 2026-10-05 à 06:30 UTC.)
|
||||
> Derniere MAJ : 2026-10-05 (**Suites de licence mergées — pile #386 → #387 → #388 en avance rapide par l'API, `main` `2cbc886`, milestone `planned-2026-10-03-suites-licence` fermée 3/3.** Produite par `/autopilot` le 2026-10-04 (15:57-18:10, 0 clarification, 0 blocage), relue par trois `/pr-review` APPROVE (24 mutations des relecteurs, 5 survivantes), les 7 suggestions appliquées en tête de pile dans `2cbc886` et chacune prouvée par une mutation rouge. Ce que voit l'utilisateur : une clé révoquée saisie en cours de session passe en Gratuite sans redémarrage ; « Retirer la clé » dans la carte Licence ; le jeton d'une ancienne licence est retiré par un refus des cours ou par la liste des machines, et « Activer » revient. Suivi #389 ; point 3 de #234 fait (run planifié 488) ; vérifications manuelles dues à la v0.17.0 dans Blockers.)
|
||||
>
|
||||
> Précédente MAJ : 2026-10-04 (**Onboarding phase 1 mergée — pile de 7 PRs #377 → #383 en avance rapide, `main` `667e058`, milestone `planned-2026-10-03-onboarding-phase1` fermée 7/7.** Produite par `/autopilot` le 2026-10-03 (19:14-20:29, 0 clarification, 0 blocage), relue par 7 `/pr-review` indépendants (42 mutations, 39 détectées), 3 suivis appliqués en tête de pile avant merge. Ce que voit l'utilisateur : états vides guidés (dashboard, Import, Transactions, Budget), liste de démarrage à 6 cases calculée depuis la base (Budget cadenassée en Free), bouton « Créer un dossier d'exemple » (2 CSV Desjardins/Tangerine, dates recalées sur les deux derniers mois), guide « Exporter un CSV depuis votre banque » (Desjardins, Tangerine, RBC, BNC, BMO). Suivis non bloquants dans #384 ; #371 (BMO sur compte réel) reste à Max ; `[Unreleased]` porte les entrées, candidate v0.17.0.)
|
||||
> Précédente MAJ : 2026-10-04 (**#350 fermée sur l'étape 3 et #346 vérifiée en production, après un resync des Blockers.** Le `/warmup` a vu que la vérification de #365 avait dû effacer le jeton de la v0.15.0 du poste Linux ; un script local en lecture seule l'a confirmé, puis la clé testeur ressaisie et « Activer » ont donné un jeton dérivé (`64 brut: False dérivé: True`). Avant de ressaisir la clé, en Gratuite par la clé révoquée, Max a vérifié #346 : la PR de #370 portera `Fixes`. Plus tôt, resync des Blockers que la synchro `8c55e26` avait laissés au 2026-10-03 (onboarding à 0/7, #365, #367/#370, maximus-api#62, la-compagnie-maximus#150, #317, `[Unreleased]`). Audit quotidien vert (run 475) ; premier tir planifié de `check-rust` le lundi 2026-10-05 à 06:30 UTC.)
|
||||
|
||||
## Position actuelle
|
||||
|
||||
|
|
@ -20,10 +20,13 @@ Audit critique de la page Bilan livré (`docs/audit-bilan-2026-05.md`, revue CPA
|
|||
|
||||
**v0.16.0 shippée** (2026-10-03, tag `v0.16.0` → CI release run 451, 7 artefacts + `latest.json` vérifiés, registre de l'updater en 0.16.0) — première version vendable de bout en bout : « Obtenir Base » ouvre la page produit (#346), le client de licence parle `/v1` et nomme chaque refus (#270), l'édition ne dépend que de la clé (#347), l'activation envoie un identifiant dérivé (#350), une clé révoquée retombe en Gratuite après un contrôle au démarrage (#365), et `rustls` 0.23.45 (#348). `[Unreleased]` vidé au tag. Aucune migration DB nouvelle (v1→v17). Sur la release publiée : #365 vérifiée et fermée le 2026-10-03, étape 10 de `/release` faite sous Linux le même jour (trace dans le corps de la release) ; reste l'étape 10 sous Windows (Michel) ; #350 fermée et #346 vérifiée le 2026-10-04.
|
||||
|
||||
**Onboarding phase 1 mergée sur `main`** (2026-10-04, `667e058`, pas encore taggée) — milestone `planned-2026-10-03-onboarding-phase1` fermée 7/7 (#351-#357, PRs #377-#383, produites par `/autopilot` le 2026-10-03 puis relues une à une par `/pr-review`) : états vides guidés (dashboard, Import, Transactions, Budget), liste de démarrage à 6 cases calculée depuis la base, bouton « Créer un dossier d'exemple », guide « Exporter un CSV depuis votre banque » (Desjardins, Tangerine, RBC, BNC, BMO). `[Unreleased]` porte ces entrées, candidate v0.17.0. Aucune migration DB (v1→v17). Suivis : #384 (non bloquants) et #371 (BMO sur compte réel, saisie de Max). **Prochaine vague prête** : `planned-2026-10-03-suites-licence` (0/3, pile #373 → #370 → #367, suites de #365), à lancer par `/autopilot planned-2026-10-03-suites-licence`.
|
||||
**Onboarding phase 1 mergée sur `main`** (2026-10-04, `667e058`, pas encore taggée) — milestone `planned-2026-10-03-onboarding-phase1` fermée 7/7 (#351-#357, PRs #377-#383, produites par `/autopilot` le 2026-10-03 puis relues une à une par `/pr-review`) : états vides guidés (dashboard, Import, Transactions, Budget), liste de démarrage à 6 cases calculée depuis la base, bouton « Créer un dossier d'exemple », guide « Exporter un CSV depuis votre banque » (Desjardins, Tangerine, RBC, BNC, BMO). `[Unreleased]` porte ces entrées, candidate v0.17.0. Aucune migration DB (v1→v17). Suivis : #384 (non bloquants) et #371 (BMO sur compte réel, saisie de Max).
|
||||
|
||||
**Suites de licence mergées sur `main`** (2026-10-05, `2cbc886`, pas encore taggées) — milestone `planned-2026-10-03-suites-licence` fermée 3/3 (#373, #370, #367 ; PRs #386 → #388, produites par `/autopilot` le 2026-10-04, relues par trois `/pr-review` APPROVE, suivis appliqués en tête de pile) : contrôle d'une clé révoquée dès sa saisie (au plus une fois par 24 h et par clé), « Retirer la clé » dans la carte Licence (place libérée d'abord sur une machine activée, contrôle quotidien arrêté), jeton d'une ancienne licence retiré sur un refus des cours ou à l'ouverture de la liste des machines. `[Unreleased]` porte l'onboarding et ces suites, candidate v0.17.0. Aucune migration DB (v1→v17). Suivi : #389 (huit autres fichiers de tests au faux `t` brut).
|
||||
|
||||
## Decisions recentes
|
||||
|
||||
- 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)
|
||||
- 2026-10-04 : **#350 fermée sur l'étape 3, sans vérification en production de l'acceptation d'un jeton brut, sur décision de Max.** Le `/warmup` a relevé que la vérification de #365 (clé Base révoquée enregistrée sur le poste Linux le 10-03) avait dû effacer le jeton de la v0.15.0, puisqu'un changement de clé l'efface (#347), alors que l'entrée du 10-03 demandait de faire #350 avant. Un script local en lecture seule (`verif-350.py`, déposé sur le poste de Max : même clé HMAC et même ordre de lecture du `machine-id` que l'app, contrôlé contre le vecteur `THIS_DERIVED` et sur 7 cas synthétiques, n'affiche ni identifiant ni clé) l'a confirmé : clé révoquée enregistrée, aucun jeton. Clé testeur ressaisie puis « Activer » : jeton émis le 2026-10-04, claim dérivé (`64 brut: False dérivé: True`), poste marqué « Cette machine ». La liste ne montre qu'une machine, aucune ligne brute active, donc les étapes 1-2 ne sont plus vérifiables : l'acceptation d'un jeton brut (ADR 0020, D1) reste gardée par `activation_token_from_before_the_derivation_still_matches` et `activation_status_accepts_a_token_from_before_the_derivation`, et un défaut ne toucherait que les installations activées par la v0.15.0 (testeurs), réparable par « Activer ». Dans la même séance, en Gratuite par la clé révoquée, **#346 vérifiée** : « J'ai déjà une clé » ferme le modal sur la carte Licence. Le corps de #370 passe donc sa PR en `Fixes #370`, sans `status:blocked` après la PR. **Leçon** : une vérification manuelle qui change la clé détruit l'état dont dépend une autre ; ordonner les vérifications d'une release par ce qu'elles consomment. Aucune migration DB (v1→v17), pas d'entrée CHANGELOG. (ref #350, #346, #365, #370)
|
||||
- 2026-10-04 : **Onboarding phase 1 livrée de bout en bout — `/plan-run` (2026-10-03) → `/autopilot` (7 PRs stackées en 1 h 15) → 7 `/pr-review` → `/merge-stack` ff (`main` `667e058`).** Trois faits d'ancrage avaient réécrit la spec : le seed IPC met 180 mots-clés dans tout profil neuf et le wizard catégorise à l'import (`useImportWizard.ts:1016`), donc la case « première règle » devient « une transaction classée à la main » (`is_manually_categorized = 1`) et les gabarits portent 7 + 4 lignes hors seed ; aucune commande Rust n'écrivait de fichier, d'où `create_sample_import_folders(import_folder, today)` avec `today` venu du webview (`chrono` compilé sans `clock`) ; une seule banque (Tangerine) a une page officielle d'export, chaque bloc du guide porte son statut de vérification. `/review-spec` avait trouvé 2 critiques (le corpus `CsvFixtureName` gelé à 15 par 6 boucles ; `DocsContent` non testable par appel direct) et corrigé une erreur du plan (33/40, pas 35/40, mesuré avec la vraie regex). Run autopilot : pile linéaire honorée malgré un graphe à 3 maillons parallélisables, pour un merge ff sans conflit `fr.json`/`en.json` ; un seul report inter-maillons (réalignement JSON du « Démarrage rapide », #355 → #357). Revues : 3 correctifs en tête de pile — statut BMO sans provenance interne (le corps d'issue avait fui dans l'UI), garde `budgetReady` sur la liste compacte (fenêtre 5/5 → 5/6 au boot), test `formatLocalDate` aveugle sous `TZ=UTC` (mutation `toISOString` vérifiée rouge). Merge : tip éprouvé en worktree `npm ci` propre (sonde rouge rc=1, tsc, 1440 vitest, build, 192 cargo), API ff du bas vers le haut avec recible de chaque enfant sur `main` → 7 PRs `merged`, pas `closed`. **Constat de process** : les workers autopilot posent `status:approved` eux-mêmes après auto-revue, le label ne prouve plus une revue indépendante (mémoire, #384). Max est client BMO, banque sans signature : la validation sur compte réel vit dans #371, la signature d'import BMO est reportée. Aucune migration DB (v1→v17). (ref #351-#357, PRs #377-#383, #384, #371)
|
||||
- 2026-10-03 : **#234 mergée (PR #375, `main` `f821492`) — le cache Rust de la CI fonctionne, `check-rust` tombe de 9 min 37 s à 3 min 22 s, et la panne tenait au VPS, pas à l'adresse `cache.host` que visait l'issue.** Diagnostic par la PR #374, fermée sans merge : ufw n'ouvrait l'hôte aux conteneurs que depuis `172.16.0.0/12`, alors que Docker (`daemon.json` de Coolify) alloue ses réseaux, ceux des jobs compris, dans `10.0.0.0/8` ; et le runner, sans fichier de config, tirait le port de son proxy de cache au hasard à chaque démarrage. Correctif appliqué par Max sur le VPS : `runner-config.yml` avec `cache.proxy_port: 28100`, passé en `--config` par un fichier complémentaire systemd, règle ufw de `10.0.0.0/8` vers ce port, ports du cache vérifiés fermés depuis Internet ; consigné avec son retour arrière dans `forgejo-ops.md` (la-compagnie-maximus `66787ea`). **Le design vient d'un constat** : le runner v12.7.0 isole ce qu'écrit un run `pull_request` sous la référence de la PR, et les autres PR ne retombent que sur les entrées non isolées. Décisions de Max : **D1** `Swatinem/rust-cache@v2` sur les PR, avec un run hebdomadaire sur `main` (lundi 06:30 UTC) et `workflow_dispatch` pour seuls écrivains du cache partagé ; **D2** pas de cache npm (`npm ci` prend 9 s). Mesuré : run 459 à froid, sauvegarde d'environ 999 Mo ; run 461 en `full match: true`, `cargo check` en 9,9 s. **`/pr-review` APPROVE**, trois suggestions appliquées dans `f821492` sans nouvelle relecture : le ménage du runner garde une entrée par clé, toutes portées confondues (une PR qui sauvegarde sous la clé partagée l'évince jusqu'au lundi) ; la clé hache aussi les variables `CARGO*`/`RUST*` du job et ignore la version de l'app ; un 404 un lundi après une semaine sans requête est une course connue du runner (forgejo/runner#1741), pas un retour de #234. **Après le merge**, `check-rust` lancé sur `main` par `workflow_dispatch` (run 464) : même clé que l'entrée de la PR, `No cache found.` (isolation prouvée), puis `Cache saved successfully` en portée partagée. **#234 reste ouverte en `status:blocked`** jusqu'à la restauration de cette entrée par la prochaine PR Rust, un premier run planifié vert le lundi 2026-10-05 et la taille de `actcache` relevée par Max ; fermeture à la main ensuite. Suite ouverte : #376 (Node 20 en fin de vie dans `check-frontend` et `audit`). Hors dépôt, `/warmup` doit filtrer les échecs `check-rust` sur l'événement `schedule`, et `forgejo-ops.md` décrire l'isolation des PR et l'éviction par clé. Aucune migration DB (v1→v17), pas d'entrée CHANGELOG (CI seule), pas de release. (ref #234, PR #375, #374, #376)
|
||||
|
|
@ -33,13 +36,13 @@ Audit critique de la page Bilan livré (`docs/audit-bilan-2026-05.md`, revue CPA
|
|||
- 2026-09-30 : **#347 mergée (PR #364, ferme aussi #360) — l'édition ne dépend plus que de la clé, et deux revues ont trouvé ce que les tests ne gardaient pas.** `/analyze` (09-29) a revérifié le corps du 09-24 contre `main` et `maximus-api`, puis fait trancher deux décisions par Max. **D12** : le jeton d'activation ne fait plus jamais retomber en Gratuite. Une clé copiée sans son jeton gardait déjà son édition, donc la règle ne protégeait rien ; elle piégeait la restauration légitime de données (#360) et toute machine activée au bout des 2 ans du jeton. **D13** : clé révoquée = drapeau de session. Livré : `LicenseError` étendu aux erreurs de saisie (`invalid_prefix`, `invalid_signature`, `malformed`, `unknown_edition`), nommées à la source par `store_license_in` et `read_license_in` ; édition résolue depuis la seule `license.key` (`entitlements_from_dir`) ; `LicenseKeyForm` extrait ; compteur n/limite, dates `fr-CA`/`en-CA`, « Sans échéance » au-delà de 50 ans ; tests de #363 absorbés. **Écart au corps de l'issue** : le drapeau révoqué vit dans `LicenseContext`, parce que le plan checker a vu que le reducer du hook meurt avec la carte. **Revue 1 (APPROVE)** : 3 mutations vertes (état « Activée » non testé à son point de décision, filtre des erreurs sous Machines, coche verte) et un défaut préexistant, le jeton d'une clé précédente qui survivait à l'enregistrement d'une autre clé (« Activée » sans « Activer », cours refusés au nom de l'ancienne licence). Corrigés dans `3f90635` : `activation_status_in`, jeton supprimé au changement de clé, carte remontée par `licenseIdentity`, message `invalidSignature` qui renvoie d'abord à la copie (`jsonwebtoken` vérifie la signature avant de décoder la charge, donc une copie abîmée finit souvent en `InvalidSignature`). **Revue 2 (APPROVE)** : course activation / nouvelle clé, badge « Activée » d'une clé révoquée, renvoi de l'ADR ; corrigés dans `cdf4df8`. Preuves : reproduction rouge sur `5d549d6`, puis 27 + 8 + 4 mutations rouges ; Rust 128 → 151, vitest 1266 → 1311, CI vérifiée dans les logs à chaque tête. Trouvé en route : le 403 `license_revoked` des cours s'affiche comme « abonnement premium requis » (consigné sur #365). Merge par l'API en `fast-forward-only`, milestone `planned-2026-09-24-paiements` fermée 3/3. Aucune migration DB (v1→v17). (ref #347, #360, #363, PR #364)
|
||||
- 2026-09-27 : **#346 mergée (PR #362) — « Obtenir Base » ouvre enfin la page produit, et la revue a trouvé que le câblage des boutons n'était gardé par aucun test.** Livré par la PR : `upsellCtaFor` (règle pure : Base achetable, Premium désactivé avec la note « pas encore offert en ligne ») ; `PurchaseButton`, `HaveKeyButton` (rendu seulement sous un routeur, via `useInRouterContext`) et `DownloadLatestButton` partagés ; `UpsellGate` suit la règle et `ProfileFormModal` le réutilise (fin du mode upsell compact) ; carte Mises à jour et page d'erreur en Gratuite ; texte de la carte Compte tranché le 09-24 ; amendement de l'ADR 0017. **`/pr-review` APPROVE**, avec un constat principal : la PR supposait que sans jsdom seules les fonctions pures se testent, or `renderToStaticMarkup` tourne dans l'environnement node de vitest et `FilterPanel.test.tsx` appelait déjà un composant comme une fonction ; six mutations des composants passaient la suite sans un rouge. **Appliqué dans `170b22d`** : 9 tests de rendu (`UpsellCtas.render.test.tsx`) ; un `logError` sur l'échec d'`openUrl` dans les trois sites qui ouvrent la page produit (`initLogCapture` ne capte pas `unhandledrejection`, donc rien n'arrivait dans Journaux) ; un commentaire dans `upsellCtaFor` (le bouton ne vend que Base, donc rendre Premium achetable sans lui donner le palier ferait vendre Base sur le Bilan) ; la réserve sur la carte Compte dans l'ADR (`check_account_edition` accorde encore Premium à un abonnement actif, chemin dormant tant qu'aucun abonnement n'est vendu) ; l'étape d'achat placée avant la saisie de la clé dans le guide et les docs intégrées ; trois corrections de CHANGELOG. **Preuve** : 12 mutations rejouées sur la tête finale dans un worktree jetable (`npm ci`), 11 rouges avec code de sortie 1. La 12e (`ProfileFormModal` sans `onNavigate={onClose}`) demande un clic et reste à vérifier à la main ; `LicenseCard` n'a pas de test, ses hooks réels empêchent de l'appeler comme une fonction. Merge par l'API en `fast-forward-only` épinglé sur `head_commit_id`, #346 fermée par `Fixes`. Aucune migration DB (v1→v17). (ref #346, PR #362)
|
||||
- 2026-09-27 : **#270 mergée (PR #359) — le client de licence parle `/v1`, nomme chaque refus, et trois revues ont trouvé ce que les tests ne gardaient pas.** `/fix-issue 270` sur le corps réécrit par le `/plan-run` du 09-24. Plan vérifié par le plan checker en 2 itérations (la 1re : un refus serveur sur cinq sans test). **Livré** : `POST /v1/licenses/{activate,deactivate,verify}` avec `product` et clé rognée dans `*_inner` ; `LicenseError` sérialisé `{code}` comme `FetchPriceError`, lu dans `error.code` de l'enveloppe (un 404 n'est jamais « route absente » ; un 404 sans code connu est `server`) ; verify répond **toujours 200**, donc `{valid:false}` devient une erreur codée au lieu de la liste vide qui affichait « Aucune machine activée » pour une clé révoquée ; corps d'un non-2xx lu sans exiger de JSON (page HTML 502 → `server`), corps 2xx illisible → `invalid_response`. TS : `parseLicenseError` + table vers 14 clés `license.errors.*` (pluriels i18next pour le délai), wrappers typés `{ok, value|error}`, hook `useLicenseMachines` à reducer exporté (erreur d'activation distincte de l'erreur de liste, parcours limite de machines en 4 requêtes sous le 5/min/IP du serveur, boutons inactifs pendant une désactivation ou un rechargement), `purchaseUrl` dans `src/shared/`. Désactivation idempotente (`no_active_activation` = fait), écart assumé et documenté. **Méthode** : chaque défaut d'origine réintroduit sur l'arbre final et compté en rouge (11 mutations) ; puis **3 passes `/pr-review`, toutes APPROVE**, dont les mutations ont trouvé 7 comportements corrects mais non gardés (un 404 lu comme clé introuvable, une table de messages comparée à elle-même, l'idempotence qui avale `license_not_found`, la relecture du statut après désactivation, `machine_name` à `null`, un 2xx illisible, deux courses de boutons) — chacun épinglé puis prouvé rouge. Une puce du CHANGELOG retirée (l'édition ne change pas visiblement après une activation) et une reformulée (l'ancienne URL est redirigée par le site depuis la-compagnie-maximus#153). **Hors PR, trouvés en route** : maximus-api#70 (réactivation d'une machine déjà désactivée → 500 ; `UNIQUE(license_id, machine_id)` sans condition sur `is_active` + `INSERT` sans `onConflict` ; reproduit sur Postgres embarqué ; upsert recommandé, sans migration ; ajouté comme prérequis sur maximus-api#62) ; #360 (jeton d'une autre machine → Gratuite, section Machines masquée, ressaisie de clé inopérante ; trois pistes, `status:triage`). Merge par l'API (rebase ff, `main` `0c9b8f8`). Aucune migration DB (v1→v17). (ref #270, PR #359, #360, maximus-api#70)
|
||||
- 2026-09-24 : **Vague paiements planifiée via `/plan-run spec-paiements` — deux milestones `planned-2026-09-24-paiements`, un défaut de licence trouvé en revue, et des clés de 100 ans.** Préambule : `/warmup` (audit quotidien vert, runs 415/416), puis commit des skills en attente depuis le 09-13 (`11e12ab` : `/issue-license`, `verify-release.sh`, garde « clés testeurs avant le tag » de `/release`) — **le courriel personnel de Michel retiré avant le premier commit** : le dépôt `Simpl-Resultat` est public et l'adresse n'était dans aucun fichier suivi ; celui de Max conservé, déjà présent dans 3 fichiers suivis. Le classifier a refusé de charger `purge-secret-forgejo` (« Git Destructive ») : scan des lignes ajoutées fait à la main. **Étape 0** : spec d'origine dans la-compagnie-maximus (07-11), corps issus de `/analyze 270` (09-13) jamais passés en `/review-spec`, donc **toutes les affirmations revérifiées** contre le code et la prod. Résultats : `verify` répond **toujours 200** (`{valid:false}` → le client affiche « Aucune machine activée » pour une clé révoquée) ; un 404 d'activate est un `license_not_found` métier, pas une route absente ; `ErrorPage` est hors routeur ; `machine_limit` est déjà dans le JWT local ; le 429 `rate_limit_exceeded` n'était traité nulle part ; `FetchPriceError` est le modèle d'erreur à reproduire. Décisions de Max D1-D8 : #153 dans la vague (seule réparation du bouton « Acheter » des v0.15.0 gratuites, qui ne recevront jamais #270) ; 409 → message + liste dépliée via verify ; note Premium « pas encore offert en ligne » ; texte exact de la carte Compte ; `removeLicense` retirée ; Windows d'abord sans détection ; #270 établit le contrat des codes d'erreur ; périmètre inchangé. **`/review-spec` (3 experts) → 🔴** : la tâche D2 effaçait le message 409 (`loadMachines()` commence par `setMachineError(null)`) et « Aucune machine » restait affichée en erreur ; le repli `activateError` (« Activation failed » en EN) contredisait #270. Constats chiffrés revérifiés à la source, aucun réfuté. **Le défaut de fond** : `signActivationJwt` signe le jeton d'activation pour **2 ans**, la clé pour 10, et le client valide le jeton avec `strict_validation()` → une machine qui a cliqué « Activer » retombe en Gratuite au bout de 2 ans, alors qu'une clé jamais activée garde son édition ; « Activer » ne rappelait pas `refresh()`. D10 : un jeton expiré mais signé pour cette machine compte comme absent (#347), ce qui corrige aussi les jetons déjà émis. **Durée des clés** : retirer l'expiration est impossible (tous les binaires installés exigent `exp`, CWE-613) ; 100 ans passe partout, et les 10 ans de la décision #15 n'étaient que le maximum du schéma de `/generate` → D9 : 100 ans hors vague (maximus-api#63, et la-compagnie-maximus#157 pour les CGV, dont « mises à jour pendant sa durée » est à reformuler) ; l'état « clé expirée le {date} » est abandonné, « Sans échéance » au-delà de 50 ans. D11 : lien « Télécharger la dernière version » en Gratuite, sans appel réseau. Lot de 9 corrections intégré : hook `useLicenseMachines` à reducer testé, `PurchaseButton` partagé, délai de 5 s et repli complet côté site, routes `/telecharger/*` et repli `latest.json` retirés, redirection sans langue, etc. **Mécanique** : milestones créées (simpl-resultat id 87, site id 88) plutôt que renommage de `spec-paiements`, qui reste le parapluie des trois dépôts ; #350 ouverte (hachage HMAC de l'identifiant machine, avant go-live). Step 9 vérifié sur l'état réel de Forgejo. **Gotcha skills** : `plan-run` Step 6bis laisse entendre qu'un seul `/autopilot <nom>` couvre deux milestones homonymes, mais `autopilot` refuse le multi-dépôts (`SKILL.md:53`) → un run par dépôt. Aucune migration DB (v1→v17). (ref #270, #346, #347, #350, la-compagnie-maximus#153/#157, maximus-api#63)
|
||||
## 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.
|
||||
- **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. **Clôture du go-live = la-compagnie-maximus#141** (`status:blocked`), qui n'attend plus que ce dépôt : l'updater vérifié (Free refuse et invite à acheter, Base accepte), #350 étant fermée depuis le 2026-10-04. 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). **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). Reste l'étape 10 de `/release` sous Windows (Michel).
|
||||
- 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` 0/3, prête pour `/autopilot`** (pile #373 → #370 → #367, `status:ready`, suites de #365) : **#373** (contrôler une clé révoquée dès sa saisie, et non au seul démarrage), **#370** (retirer la clé enregistrée, seul moyen d'arrêter le contrôle quotidien d'une clé révoquée sans entrer une autre clé ; sa PR portera `Fixes #370`, la vérification manuelle de #346 étant faite le 2026-10-04), **#367** (jeton d'activation d'une ancienne licence resté à côté d'une autre clé par la v0.15.0 ; carte « Activée », cours refusés, aucun moyen de réactiver). 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) ; reste de #363 (plafond de `/issue-license` à 36525 jours et essai d'une vraie clé de 100 ans, débloqués par le déploiement de maximus-api#63) ; 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) ; clôture du go-live = la-compagnie-maximus#141 seule, maximus-api#62 étant fermée ; `spec-paiements` reste le parapluie des trois dépôts (ici 4/5, reste #363) ; 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` **3/4** (#232 livrée le 2026-07-27 ; **#234** : connectivité du cache réparée sur le VPS et `Swatinem/rust-cache` mergé le 2026-10-03 par la PR #375, mais l'issue reste ouverte en `status:blocked` jusqu'aux vérifications d'après merge — le premier run de la prochaine PR Rust (la pile `suites-licence` en produira) restaure l'entrée partagée, le premier run planifié du lundi 2026-10-05 à 06:30 UTC est vert avec `Cache up-to-date.` ou `Cache saved successfully` dans son log (une sauvegarde ratée laisse le job vert), Max relève de nouveau la taille de `/home/ubuntu/.cache/actcache` sur le VPS (2,0 Go le 2026-10-03, deux entrées de 999 Mo sous la même clé ; attendu vers 1 Go après le passage du ménage du runner) — puis sera fermée à la main ; la milestone reste à 3/4 d'ici là) ; **#376** (`status:triage` : Node 20, en fin de vie depuis le 2026-04-30, encore installé par `check-frontend.yml` et `audit.yml`, et commentaire `concurrency` de `check-rust.yml` démenti par `forgejo-ops.md` pour les runs de PR). 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.
|
||||
- **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. **Clôture du go-live = la-compagnie-maximus#141** (`status:blocked`), qui n'attend plus que ce dépôt : l'updater vérifié (Free refuse et invite à acheter, Base accepte), #350 étant fermée depuis le 2026-10-04. 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 suites de licence y ajoutent deux textes à poster par Max (contrôle à la saisie, retrait de la clé), dans les corps des PRs #386 et #387. **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). Reste l'étape 10 de `/release` sous Windows (Michel).
|
||||
- **Vérifications manuelles dues à la v0.17.0** (onboarding + suites de licence ; sur la release ou un build de `main`, Linux puis Windows), dans un ordre qui ne détruit le jeton d'activation qu'à la fin de ce qui en dépend : (1) #370, machine activée hors ligne → « Retirer la clé » : seconde confirmation qui donne la raison, Annuler ne change rien, sauts de ligne des fenêtres ; (2) #367, s'il existe un second poste avec la même clé : y désactiver ce poste, puis ouvrir ici la liste des machines → « Activer » revient sans recharger, ligne au Journal ; (3) #370 en ligne → place libérée, carte en Gratuite ; (4) #373 et #370 avec la clé révoquée du 2026-09-30 : Base une à deux secondes puis Gratuite, ligne « License check: the license server says the key was revoked » ; retirée → aucune désactivation envoyée, puis au redémarrage « no valid key stored, nothing sent » ; ressaisie → reste en Gratuite ; (5) clé testeur Premium ressaisie, « Activer », `verif-350.py` rend `64 brut: False dérivé: True` ; (6) #367, dossier v0.15.0 (clé A à côté du jeton d'une licence B révoquée) : couvert par un test de bout en bout, à faire seulement si un tel dossier existe encore. Plus la liste QA de l'onboarding (`docs/qa-onboarding.html`).
|
||||
- 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) ; reste de #363 (plafond de `/issue-license` à 36525 jours et essai d'une vraie clé de 100 ans, débloqués par le déploiement de maximus-api#63) ; 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) ; clôture du go-live = la-compagnie-maximus#141 seule, maximus-api#62 étant fermée ; `spec-paiements` reste le parapluie des trois dépôts (ici 4/5, reste #363) ; 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` **3/4** (#232 livrée le 2026-07-27 ; **#234** : connectivité du cache réparée sur le VPS et `Swatinem/rust-cache` mergé le 2026-10-03 par la PR #375, l'issue reste ouverte en `status:blocked` pour le seul point 4 : points 2 et 3 faits (PR #386, run 480 ; run planifié du lundi 2026-10-05, run 488 : `full match: true`, `Cache up-to-date.`, 3 min 27 s), reste à relever `du -sh /home/ubuntu/.cache/actcache` sur le VPS (2,0 Go le 2026-10-03, attendu vers 1 Go) — puis fermeture à la main ; la milestone reste à 3/4 d'ici là) ; **#376** (`status:triage` : Node 20, en fin de vie depuis le 2026-04-30, encore installé par `check-frontend.yml` et `audit.yml`, et commentaire `concurrency` de `check-rust.yml` démenti par `forgejo-ops.md` pour les runs de PR). 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. Restent **#317** (prémisse caduque depuis le 2026-09-26 : `react-router-dom` 7.18.2 et suivantes corrigent l'advisory par un bump de patch dans `^7.18.1`, sans migration v8 ; absorbée par #358, dont la PR la fermera), **#319** (déclencheur de retrait pour `rsa`, désormais **seule** entrée de `.cargo/audit.toml` — le garde-fou est passé à 2 vérifications) et **#345** (domicilier la contrainte `windows-sys 0.61.2` — analysée le 09-04 : le corps d'origine, écrit de mémoire en fin de revue, se trompait sur trois points. Le déclencheur n'est pas « n'importe quel `cargo update` » mais tout bump atteignant le sous-arbre réseau/TLS — mesuré : `-p anyhow` ne bouge rien, `-p hyper` fait descendre les 7 — soit précisément là où tombent les advisories. **Prémisse restreinte le 2026-09-21 par #348** : `-p rustls`, au cœur de ce même sous-arbre, n'en déplace **aucun** — le déclencheur tient à `hyper` et à ce qu'il tire, pas à la couche TLS en général, donc « sous-arbre réseau/TLS » prédit une dérive là où il n'y en a pas et ferait écrire une strophe à la main sans nécessité. D'où la suggestion portée en commentaire sur l'issue : formuler le garde-fou sur la **version résolue de `windows-sys`** plutôt que sur une liste de crates déclencheurs — la liste est ce qui vient d'être trouvé faux, la version est ce qui est protégé. #310 avait **bien** vu la dérive et l'avait jugée inoffensive *sur Linux*, où elle l'est ; son coût tombe sur le build Windows que personne ne mesurait : **3 versions de `windows-sys` compilées contre 5**. Aucun risque de correction — les 7 crates déclarent des bornes larges couvrant les deux états. Et cargo annonce « Locking 1 package » en écrivant 8 changements, donc le silence est le sien. Décision : garde-fou CI sur la version + ADR portant la condition de sortie. Le check croisé Windows depuis Linux a été **testé et écarté** — `cc-rs` s'arrête sur `lib.exe`, il faudrait `cargo-xwin`). Côté npm, **#358** ouverte le 2026-09-26 par `/analyse-vulnerabilite` : `npm audit` remonte 7 findings (4 high, 3 moderate) sur 4 dépendances racines, contre les 2 acceptés au 07-27, et chaque correctif tient dans la borne déjà déclarée ; le lock se régénère avec `npx npm@11` (npm 10 plante sur un bump de vitest 4.1.x).
|
||||
- Nouveau bug ouvert : **#320** — les installations `.rpm` ne reçoivent aucune mise à jour (`latest.json` ne porte qu'une entrée `linux-x86_64` construite depuis le `.deb`, `release.yml:104-122`), alors que les `.rpm` continuent d'être publiés en assets. Documenté en §3 de `docs/qa-update-cycle.md` (« ne pas tester : cassé, pas seulement non vérifié »).
|
||||
- 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.16.0 (2026-10-03) ; `[Unreleased]` porte l'onboarding phase 1, candidate v0.17.0.
|
||||
- **É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.16.0 (2026-10-03) ; `[Unreleased]` porte l'onboarding phase 1 et les suites de licence, candidate v0.17.0.
|
||||
|
|
|
|||
Loading…
Reference in a new issue