49 KiB
STATE — Simpl'Résultat
Derniere MAJ : 2026-10-08 (Parcours de démarrage guidé mergé — pile #402 → #407 en avance rapide par l'API,
mainee17f31, milestoneplanned-2026-10-06-onboarding-parcours-guidefermée 6/6. Six/pr-reviewAPPROVE, puis sept commits en tête de pile sur décision de Max, dont la voie A : l'étape « Importer un premier fichier » ne compte plus qu'un fichier qui a amené une transaction. Suites #408 et #409. Restent les vérifications manuelles sur un build, à faire avec celles de #390.)Précédente MAJ : 2026-10-06 (#390 mergée — PR #394 en avance rapide par l'API,
main5910387. L'étape 5 de la liste de démarrage se coche enfin. Les profils secondaires rattrapent les migrations qu'ils n'avaient jamais reçues. Sous Linux, les commandes cherchent les bases dans le bon dossier. #390 reste ouverte enstatus:blockedjusqu'à la liste post-merge. Suivis de revue en #395.)
Position actuelle
v0.9.1 shippée (2026-05-10). Milestones spec-refonte-rapports, spec-refonte-seed-categories-ipc, spec-price-fetching, overnight-2026-04-26-bilan et overnight-2026-04-27-prices complétées et fermées. Maximus-api 0.3.0 LIVE en prod (api.lacompagniemaximus.com) — pubkey Ed25519 alignée, smoke test Phase B (#161) validé. Backlog actif concentré sur spec-monetisation (7/12) : activation en ligne (#53), pipeline Stripe desktop (#50, #52) et maximus-api Stripe webhooks (#135, #136).
Audit critique de la page Bilan livré (docs/audit-bilan-2026-05.md, revue CPA + UX). Étape 0 — quick wins terminologie « catégorie »→« type », symbole optionnel, date de snapshot déplaçable — mergée (#201, issues #198/#199/#200 fermées). Chantier structurel = Étapes 1-2 de l'audit (séparation véhicule fiscal × classe d'actif via vehicle_type, puis détail par titre balance_securities+holdings+book_cost, bascule agrégé→détaillé, réouverture ADR 0012). Étape 1 livrée (sprint 2026-06-01 : PRs #206-#209 mergées, milestone overnight-2026-06-01-bilan-axe-vehicule fermée 4/4) — vehicle_type nullable = enveloppe fiscale portée par le compte, catégorie = pure classe d'actif (5 classes), migrations additives v12/v13 (v1-v11 intactes), renommage via custom_label (fix bug I), axe graphique classe/enveloppe + rendements repliables persistés ; ADR 0014 Accepted, ADR 0012 Rejected. CHANGELOG sous [Unreleased] (pas encore taggé). Étape 2 livrée (merge manuel 2026-06-09 : pile de 9 PRs stackées #219-#227 mergées bottom-up, milestone overnight-2026-06-05-bilan-detail-titres à 9/10, issues #210-#218 fermées) — détail par titre via balance_securities + balance_snapshot_holdings, balance_accounts.kind ('simple'|'detailed') + detailed_since, migrations additives v14/v15/v16 (v1-v13 intactes), conversion des comptes cotés existants en détaillés 1-position (v16), service securities transactionnel, reducer holdings + dispatch account.kind, UI multi-titres (SecurityPicker), assistant détailler-un-compte (date pivot), drill-down par titre + gain latent, tests intégration/régression ; ADR 0015 Accepted. #228 mergé (PR #229, fix-forward : garde d'abort v16 scopée aux comptes convertibles via JOIN balance_categories + c.asset_type IS NOT NULL dans les 3 copies — Migration v16 / V16_SQL / V16_CORRUPT — + test régression ; CI vert car #229 ciblait main) → milestone overnight-2026-06-05-bilan-detail-titres complète 10/10 et fermée. v0.10.0 shippée (2026-06-29 : Étapes 1+2 du bilan, migrations v12→v16) puis hotfix v0.10.1 (2026-06-30, PR #230, déployé) — corrige un « database is locked » introduit en 0.10.0 (apparaissait après l'abandon d'un snapshot en cours) : tout l'accès DB est désormais sérialisé via withTransaction dans db.ts (tauri-plugin-sql = pool sqlx multi-connexions sans primitive de transaction JS → BEGIN/COMMIT en db.execute séparés pouvaient strander une transaction d'écriture = verrou zombie), appliqué aux 5 sites transactionnels ; + console de log live-update + API logInfo/logWarn/logError. 20 tables / 24 index, 16 migrations (v1→v16).
Milestone deps-security-2026-07 livrée (2026-07-01, 4/4 fermée) — 4 vulns de dépendances Defenseur remédiées en 2 PRs (#239 react-router-dom 7.18.1 ; #240 vite 6.4.3 + vitest 4.1.9) ; npm audit 5→0 — le dernier @babel/core low remédié le 2026-07-04 (override scopé @vitejs/plugin-react→@babel/core@^7.29.7, issue #241 / PR #242 mergée). Ce « 0 » n'est plus l'état courant : des advisories publiées depuis l'ont ramené à 3, traitées en #311 le 2026-07-27 → 2 restantes, acceptées (react-router, cf. entrée du jour). Nouveau milestone spec-ci-build-optimization (2/4) ouvert (baseline #231 : cause #2 = reserveCache timeout du runner ; #234 connectivité cache VPS, #232 split workflows).
v0.11.0 shippée (2026-07-05, tag v0.11.0 → CI release Windows/Linux + JSON updater) — milestone overnight-2026-07-05-bilan-rapports-ux complétée 5/5 et fermée via un run /autopilot (5 workers séquentiels, PRs #248-#252 toutes /pr-review APPROVE, puis merge local de la pile + réconciliation Forgejo). Contenu : rapport comparable réel-vs-réel hiérarchique avec sous-totaux (#247) ; netting des transferts ciblé (catégories type transfer → SUM signé ~0, autres types inchangés au byte) dans le compare (#243) ; landing Bilan en tuiles HubReportNavCard + guard empty-state découplé + gestion comptes accessible partout (#244) ; import CSV de titres dans un snapshot détaillé (front pur, autoDetectHoldingColumns, prix flexible) (#245) ; cible de migration catégories éditable sur chaque ligne + type-ahead CategoryCombobox feuilles-seulement (#246). Aucune migration DB (v1→v16 inchangées), 20 tables / 24 index, 16 migrations. Point de suivi non bloquant : nets de transfert signés traversent du code UI compare pensé pour des magnitudes positives (mord seulement les transferts déséquilibrés à une jambe).
v0.12.0 shippée (2026-07-05, tag v0.12.0 → CI release #311) — recadrage de #243 (montants de transfert inclus dans le comparable) par Max en « analyse de résultat » : deux rapports comparables refondus en états de résultat (income statement). Le compare réel-vs-réel (#253) et le tableau de tendance par catégorie (#256) affichent le revenu, un Résultat avant transferts (revenus − dépenses) et un Résultat net (après transferts), sections ordonnées revenu→dépense→transfert ; les rapports comparables ouvrent par défaut sur le mois complet précédent (#253). Modules purs extraits et testés (compareResults.ts, overTimeResults.ts) ; 2 blocages /pr-review corrigés (fuite du revenu dans les top-movers Cartes ; garde StrictMode sur le sync du mois de référence). Livré en 2 issues/PRs stackées #255→#257 (merge local + réconciliation Forgejo, branches supprimées), 701 vitest verts, aucune migration DB (v1→v16 inchangées), 20 tables / 24 index. Backlog ouvert au passage : #258 (db-locked proposeStarterAccounts) → fermé le 2026-07-07 (déjà corrigé v0.10.1, pas de nesting) ; #254 (collapse/expand) → livré le 2026-07-07 (PR #261) ; #259 (mapping manuel d'un compte standard sans similaire auto) et #260 (epic « rapports uniformes » — tous les rapports sur le modèle income-statement) ouverts.
v0.15.0 shippée (2026-09-12, tag v0.15.0 → CI release run 402, 7 artefacts + latest.json vérifiés) — première version où le gating par édition est actif : sans clé, Budget, Ajustements, rapports avancés, profils multiples, Bilan et mises à jour automatiques sont verrouillés (données intactes, ADR 0017). Les deux testeurs (Max, Michel) ont une clé Premium émise avant le tag. [Unreleased] vide. Aucune migration DB nouvelle (v1→v17). Étape 10 de /release consignée le 2026-09-13 : cycle réel v0.14.0 → v0.15.0 validé par les deux testeurs, trace rédigée pour le corps de la release Forgejo (invite polkit Linux non consignée, .rpm hors test → #320).
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, publiée dans la v0.17.0) — 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). 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, publiées dans la v0.17.0) — 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. Aucune migration DB (v1→v17). Suivi : #389 (huit autres fichiers de tests au faux t brut).
v0.17.0 shippée (2026-10-05, tag v0.17.0 sur 07255e1 → CI release run 491 en 22 min, 7 artefacts + latest.json vérifiés par verify-release.sh, endpoint de l'updater en 0.17.0) — onboarding phase 1 et suites de licence. [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. Restent les vérifications manuelles sur la release publiée (Blockers) et, de la v0.16.0, le cycle de mise à jour Windows (Michel).
Parcours de démarrage guidé mergé sur main (2026-10-08, ee17f31, non publié) — milestone planned-2026-10-06-onboarding-parcours-guide fermée 6/6 (#396-#401, PRs #402 → #407, produites par /autopilot le 2026-10-08, relues par six /pr-review APPROVE, suivis appliqués en tête de pile) : bandeau « Démarrage n/N · Étape suivante » sur chaque page, cartes d'étape avec mise en évidence du contrôle sur Import, Transactions et Budget, état partagé par un fournisseur et canal d'événements de données (ADR 0022), règle D9 (un profil déjà actif trouve le parcours masqué). [Unreleased] porte aussi #390. Aucune migration DB (v1→v17). Suivis : #408 (db.ts hors verrou pendant une transaction) et #409 (harnais de test).
Decisions recentes
- 2026-10-08 : Parcours de démarrage guidé livré de bout en bout —
/autopilot(6 PRs stackées en 3 h, CI verte à chaque maillon) → six/pr-reviewAPPROVE → sept commits en tête de pile → merge ff par l'API (mainee17f31).- Revues : aucun bloquant, un verdict indépendant par PR (commentaires 20659 à 20730) ;
status:approvedposé par les seuls relecteurs, les workers ayant laisséstatus:review(skill corrigé). - Décision de Max : voie A sur le critère de #398 « pas de « Fait. » pour un import qui n'ajoute rien ». Le relecteur a corrigé le rapport du run : les doublons seuls sont sans effet (leurs transactions sont venues avec un fichier
completed) ; le vrai cas est l'import sans ligne valide (en-tête seul, format mal détecté), qui cochait l'étape 4 et faisait boucler /transactions et /import. L'étape compte désormais lesimported_filesencompletedayant au moins une transaction (EXISTSsurtransactions.file_id, indexidx_transactions_file), avec une entrée Corrigé : la v0.17.0 a déjà le défaut. - Autres suivis en tête : D9 lit son drapeau hors transaction, donc plus de
BEGIN/COMMITà chaque ouverture, pendant lesquelsdb.tslaisse tout passer hors verrou ;:focus-visible { outline: revert }sur le contrôle entouré (WCAG 2.4.7) ; carte Budget sans cible sur l'état vide ; épingles (séquence réelle du reducer, phrase selon le filtre, notification de restauration hors verrou, fuseau du test du mois) ; docs et liste QA à 44 cas. - Preuves : 16 mutations sur ces correctifs, toutes rouges, dont 4 survivantes des revues ; compteur rejoué avec sqlite3 sur le schéma consolidé ; tip en worktree
npm cipropre (sonde rc=1, build, 1904 vitest) ; CI 507. Les commits ajoutés après la revue, non relus, sont nommés dans le commentaire 20835 de #407. - Merge : chaque enfant reciblé sur
mainpuis mergé en ff épinglé, branches gardées jusqu'au dernier merge puis supprimées, donc 6 PRsmerged. #384 : trois items cochés (réglés par la pile), #382 en partie. - Acquis : au
/plan-run, confronter un critère à la définition du compteur hérité qu'il suppose (celui de l'étape 4 venait de la phase 1). - Aucune migration DB (v1→v17). (ref #396-#401, PRs #402-#407, #408, #409, #384)
- Revues : aucun bloquant, un verdict indépendant par PR (commentaires 20659 à 20730) ;
- 2026-10-06 : #390 mergée (PR #394,
main5910387) — l'étape 5 de la liste de démarrage se coche, les profils secondaires rattrapent leurs migrations, et les bases sont cherchées dans le bon dossier sous Linux.- Constat : en testant l'onboarding de la v0.17.0, Max a vu que classer une transaction ne cochait pas l'étape 5.
- Cause : depuis la v0.1.0,
updateTransactionCategorylie un booléen JS. tauri-plugin-sql 2.3.2 le stocke en texte'true', que le compteur= 1ne trouve pas. - Deux défauts plus anciens, trouvés en corrigeant :
- tauri-plugin-sql ne migre que
simpl_resultat.db. Un profil secondaire gardait le schéma de sa création ; il existe sept états publiés depuis la v0.3.0. - Le plugin range les bases sous
app_config_dir().repair_migrations,delete_profile_dbetcompute_account_returncherchaient sousapp_data_dir(), dossier différent sous Linux seulement. Supprimer un profil laissait sa base sur le disque, et les rendements du Bilan s'affichaient en tirets.
- tauri-plugin-sql ne migre que
- Décisions de Max : réparer les drapeaux à l'ouverture de chaque profil plutôt que par une v18 ; inclure le rattrapage dans #390 ; appliquer les suggestions rapides de la revue, puis merger.
- Livré :
toSqlFlag, à l'écriture et à la restauration d'une sauvegarde ;prepare_profile_db: plancher déduit du schéma, copieVACUUM INTOavant la première écriture, historique_sqlx_migrationsau format sqlx, clés étrangères actives avec une seule reprise ciblée, réparation des drapeaux texte, échec ouvert ;- l'historique écrit dès la création d'un profil ;
profile_db_path: dossierapp_config_dir()et nom de fichier validé ;- l'ADR 0021, et les amendements des ADR 0003 et 0005.
- Preuves :
- les sept états publiés sont rejoués en fixtures ;
- 22 mutations de l'auteur, toutes rouges ;
- le plan checker a refusé trois fois (dossier Linux, rejeu de v2, clés étrangères), puis Max a validé la suite ;
/pr-reviewAPPROVE sur71147c5;- les quatre suggestions rapides sont appliquées en tête (
5910387, des tests seulement, non relu), les quatre autres sont reportées en #395 ; - tête éprouvée dans un worktree propre : sonde rc=1, 1520 vitest, 255 Rust, CI 495 et 496.
- Suite : #390 reste ouverte en
status:blockedjusqu'à la liste post-merge. - 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 tip8f964e0: build, 1498 vitest,cargo checksans avertissement, 224 Rust ;.claude/worktrees/vide. Avant le bump, diff vide depuisv0.16.0surCargo.lock,Cargo.toml,release.yml,tauri.conf.jsonetpackage*.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 deCLAUDE.md,Cargo.lockédité à la main et accepté parcargo metadata --locked. Tag annoté confirmé par Max, poussé seul (jamais--tags). Run 491 en 22 min ;verify-release.shvert (7 artefacts, signatures et URL en 0.17.0) ; l'endpoint detauri.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 milestonespec-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-reviewAPPROVE → suivis en tête de pile → merge ff par l'API (main2cbc886). #373 : contrôle de révocation à la saisie, en arrière-plan, sous un verroutauri::async_runtime::Mutexqui 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.checkgardé ; libération préalable pardeactivate_idempotent+note_revocation, jamaisdeactivate_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 403license_revokeddes 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 », deuxtoubliés,Storagedestore_license_in, jeton non UTF-8) et deux autres suggestions (rechargement après un retrait en échec, budget de 6 requêtes) appliquées dans2cbc886, prouvées par 2, 18, 4, 1, 10, 1 et 1 tests rouges. Tip validé en worktreenpm cipropre (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 fauxtqui rend la clé brute rend invisible touttoublié (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
/warmupa 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 dumachine-idque l'app, contrôlé contre le vecteurTHIS_DERIVEDet 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 paractivation_token_from_before_the_derivation_still_matchesetactivation_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 enFixes #370, sansstatus:blockedaprè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-stackff (main667e058). 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)avectodayvenu du webview (chronocompilé sansclock) ; une seule banque (Tangerine) a une page officielle d'export, chaque bloc du guide porte son statut de vérification./review-specavait trouvé 2 critiques (le corpusCsvFixtureNamegelé à 15 par 6 boucles ;DocsContentnon 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 conflitfr.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), gardebudgetReadysur la liste compacte (fenêtre 5/5 → 5/6 au boot), testformatLocalDateaveugle sousTZ=UTC(mutationtoISOStringvérifiée rouge). Merge : tip éprouvé en worktreenpm cipropre (sonde rouge rc=1, tsc, 1440 vitest, build, 192 cargo), API ff du bas vers le haut avec recible de chaque enfant surmain→ 7 PRsmerged, pasclosed. Constat de process : les workers autopilot posentstatus:approvedeux-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,
mainf821492) — le cache Rust de la CI fonctionne,check-rusttombe de 9 min 37 s à 3 min 22 s, et la panne tenait au VPS, pas à l'adressecache.hostque visait l'issue. Diagnostic par la PR #374, fermée sans merge : ufw n'ouvrait l'hôte aux conteneurs que depuis172.16.0.0/12, alors que Docker (daemon.jsonde Coolify) alloue ses réseaux, ceux des jobs compris, dans10.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.ymlaveccache.proxy_port: 28100, passé en--configpar un fichier complémentaire systemd, règle ufw de10.0.0.0/8vers ce port, ports du cache vérifiés fermés depuis Internet ; consigné avec son retour arrière dansforgejo-ops.md(la-compagnie-maximus66787ea). Le design vient d'un constat : le runner v12.7.0 isole ce qu'écrit un runpull_requestsous 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 : D1Swatinem/rust-cache@v2sur les PR, avec un run hebdomadaire surmain(lundi 06:30 UTC) etworkflow_dispatchpour seuls écrivains du cache partagé ; D2 pas de cache npm (npm ciprend 9 s). Mesuré : run 459 à froid, sauvegarde d'environ 999 Mo ; run 461 enfull match: true,cargo checken 9,9 s./pr-reviewAPPROVE, trois suggestions appliquées dansf821492sans 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 variablesCARGO*/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-rustlancé surmainparworkflow_dispatch(run 464) : même clé que l'entrée de la PR,No cache found.(isolation prouvée), puisCache saved successfullyen portée partagée. #234 reste ouverte enstatus:blockedjusqu'à la restauration de cette entrée par la prochaine PR Rust, un premier run planifié vert le lundi 2026-10-05 et la taille deactcacherelevée par Max ; fermeture à la main ensuite. Suite ouverte : #376 (Node 20 en fin de vie danscheck-frontendetaudit). Hors dépôt,/warmupdoit filtrer les échecscheck-rustsur l'événementschedule, etforgejo-ops.mddé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) - 2026-10-03 : v0.16.0 taggée et publiée (
56fc612, run 451 vert) — sur le constat de Max qu'il n'y a pas d'autres utilisateurs que les testeurs, les vérifications manuelles passent après la publication. Aucune PR ouverte à merger. Pré-vol du skill sur le tip6625d25: build, vitest 1348,cargo checksans avertissement, 187 Rust ; aucun worktree résiduel ; les deux testeurs ont une clé Premium valide depuis la v0.15.0 et rien ne toucheFEATURE_TIERS. Version mineure (fonctionnalités ajoutées) : 5 manifestes, 2 changelogs et la ligne deCLAUDE.md,Cargo.lockédité à la main et accepté parcargo metadata --locked. Tag annoté confirmé par Max avant le push, poussé seul (jamais--tags). Run 451 en 22 min ;verify-release.shvert ; l'endpoint detauri.conf.json(registre de paquets) sert la 0.16.0, au-delà de la copie attachée à la release que lit le script. Correction faite en route : j'avais écrit que les installations Base+ recevraient la mise à jour d'elles-mêmes ;docs/qa-update-cycle.mdet le code disent l'inverse, aucune vérification automatique, quatre déclencheurs manuels. Personne ne reçoit donc la release sans cliquer « Vérifier les mises à jour ». Étape 10 due (rustls0.23.45 est sur le chemin TLS de l'updater) : Linux par Max, enchaînée avec #350 sur le poste activé en v0.15.0 (à faire avant tout changement de clé, qui efface le jeton) ; Windows par Michel. Trace à consigner dans le corps de la release. En parallèle : la-compagnie-maximus#184 (politique de confidentialité) par Max ; #370 ouverte (retrait de la clé,status:triage). Tests de Max le jour même : mise à jour Linux v0.15.0 → v0.16.0 réussie, trace consignée dans le corps de la release (invite d'authentification apparue, type non noté ; Windows à dérouler par Michel) ; #365 vérifiée avec la clé réellement révoquée et fermée. Anomalie relevée : saisie en cours de session, cette clé gardait l'édition Base jusqu'au clic sur « Activer », comportement livré (contrôle au démarrage seulement) → #373 propose le contrôle dès la saisie. La vérification de #346, qui demande une édition Gratuite propre, est reportée à #370 (instructions ajoutées à son corps) ; #372 ouverte (la liste complète des versions repousse le Journal en bas de Paramètres → Systèmes). Aucune migration DB (v1→v17). (ref v0.16.0, #270, #346, #347, #348, #350, #365, #370, #372, #373) - 2026-10-03 : #365 mergée (PR #368,
mainb107cf4) — une clé révoquée retombe en Gratuite, et l'app envoie pour cela sa première requête non sollicitée. Constat du go-live (09-30) : une licence remboursée, révoquée côté serveur, restait pleinement fonctionnelle, parce que l'édition se résout hors ligne depuis la clé et que le drapeau de #347 (D13) ne vivait que la session./analyze(10-01) : D1 contrôle au démarrage, au plus une tentative par 24 h ; D2 révocation nommée là où le verrou apparaît, sans bandeau global ; D3 fail-open ; D4 un seul état. Livré :license.checkà côté de la clé ({key_sha256, attempted_at, revoked}, condensé SHA-256, jamais la clé) ;entitlements_from_dirrend("free", [])pour une clé révoquée,auto-updatecompris ;check_license_revocation(POST /v1/licenses/verify, produit et clé seulement, rien sans clé valide, tentative écrite avant l'appel, seulvalid:truelève et seul « révoquée » pose) ; l'activation, la liste et la désactivation enregistrent unlicense_revokedsous la clé envoyée ;LicenseContextlitinfo.revoked(fin demarkRevoked), lance le contrôle une fois par démarrage, écrit son issue dans le Journal et ne recharge que si l'état change ; une clé révoquée ressaisie reste en Gratuite ; carte Licence,UpsellGateet carte Mises à jour nomment la révocation ; amendement #365 de l'ADR 0017. Écart tranché par Max le 10-02, après trois échecs du plan checker : la route des cours nomme le 403license_revokedsans l'enregistrer, parce que/v1/pricesjuge la licence du jeton d'activation, que le client ne relie pas à la clé, et que la v0.15.0 laissait le jeton d'une clé précédente à côté d'une nouvelle (git show v0.15.0) : l'enregistrer aurait rétrogradé une clé valide. Ce jeton périmé est suivi en #367. Preuves : 33 mutations Rust et 27 front de l'auteur, toutes rouges ; la première passe en avait laissé 5 vertes pour 4 manques, corrigés dans4225dad, dont la tentative écrite après la requête (un test lit maintenant le fichier d'état depuis le serveur mockito, pendant que la requête est en vol) et l'intervalle de 24 h que suivaient les lignes construites depuis la constante (mesuré sure24c30f: 184 verts avec l'intervalle à 1 h). Contrat sondé en production :verifyd'une clé factice répond200 {"valid":false,"reason":"not_found"}./pr-reviewAPPROVE (37 mutations du relecteur, 35 rouges). Appliqué dansb107cf4: le test « une tentative non inscriptible n'envoie rien » (mutation de la revue : 0 rouge sur 185, puis 1 sur 187) et celui du verdict non inscriptible ;storagereformulé, puisqu'il couvre aussi un verdict non écrit. Décisions de Max le 10-03 : une clé révoquée reste contrôlée une fois par 24 h tant qu'elle est enregistrée, et c'est déclaré dans le guide (aucune interface ne retire une clé : seul l'enregistrement d'une autre l'arrête) ; la carte Mises à jour nomme la révocation, la page d'erreur non. Rust 168 → 187, vitest 1314 → 1348, CI lue dans les logs (runs 446/447 puis 449/450). Hors PR : la-compagnie-maximus#184 corrigée, son commentaire du 10-02 disant à tort que l'édition Gratuite ne fait jamais cette requête. Non gardé par les tests : l'effet du fournisseur React qui lance le contrôle, l'enregistrement de la commande danslib.rset la réponse réelle du serveur pour une clé révoquée, d'où la vérification manuelle. Acquis : la fermeturematch_requestde mockito tourne pendant que la requête est en vol, ce qui prouve un ordre « écrit avant la requête » ; une suite Rust rouge imprimeerror: test failed, donc seulcould not compilesignale une erreur de compilation. Aucune migration DB (v1→v17). (ref #365, PR #368, #367, la-compagnie-maximus#184) - 2026-10-01 : #350 mergée (PR #366,
main0a9c9f7) — l'activation envoie un identifiant dérivé, et l'issue reste ouverte pour une vérification manuelle due avant le tag./warmup(audit quotidien vert, 10 runs d'affilée), puis/analyze 350: le corps du 09-24 n'avait jamais été édité (sa timeline ne porte que des références), et #270, #347 et le go-live l'avaient périmé sur quatre points — « avant go-live », « retomberaient en Gratuite » (faux depuis D12),current_entitlementsqui ne compare plus rien au jeton,get_machine_idsans appelant. Trois sites manquaient : la suppression du jeton dansdeactivate_machine_impl, le marqueur « Cette machine » deLicenseCard, et le Bearer des cours, qui envoie un jeton antérieur avec son claim brut. Décisions de Max : D1 une machine déjà activée garde son activation (jeton brut accepté) ; D2 le critère « aucun identifiant brut ne quitte le poste » est borné aux activations faites avec la version corrigée ; D3 le client ne suppose rien du serveur. Deux suites ouvertes dans leurs dépôts : maximus-api#82 (identifiants bruts déjà stockés, lignes désactivées comprises) et la-compagnie-maximus#184 (la politique de confidentialité ne déclare aucune donnée d'activation). Livré :derive_machine_id(HMAC-SHA256sous la clé figéecom.simpl.resultat/license-machine-id/v1, 64 caractères hexadécimaux, identifiant vide refusé) ;MachineIds(dérivé et brut) ; activation qui dérive juste avant l'appel et exige le dérivé dans le jeton reçu ;is_this_machinecalculé côté Rust pour les deux formes ; règle de suppression du jeton à la désactivation ;get_machine_idretirée etActivationStatussans identifiant ; ADR 0020. Aucune dépendance ajoutée,Cargo.lockintact. Écarts au corps de l'issue, déclarés dans la PR : la règle de suppression est plus large que la phrase de l'issue (toute ligne de ce poste emporte le jeton, sauf l'ancienne ligne brute quand le jeton vaut pour la ligne dérivée), parce que la règle littérale laissait un jeton expiré sur le disque ; la liste, la désactivation et l'état d'activation n'échouent plus sur un identifiant du système illisible. Plan checkerpassau premier tour, ses remarques mineures intégrées : tests épinglés sur les vecteurs en littéraux, « aucun appel » observé contre un mock et non déduit./pr-reviewAPPROVE, cinq suggestions appliquées dans0a9c9f7: la condition de retrait de l'ADR, reprise du corps de l'issue, comptait deux ans depuis la v0.15.0, or une v0.15.0 gratuite ne se met plus à jour et peut encore activer en brut des mois plus tard, donc la borne est la dernière émission d'un jeton brut, connue du serveur seul ; « plus aucune commande ne remet l'identifiant du système au webview » était plus large que le code (la liste porte encore la ligne brute d'une activation antérieure) ; deux lignes de test ; la seconde ligne que crée une réactivation tant que le serveur n'a pas rehaché ses lignes ; la vérification manuelle par la valeur et non par la longueur. Preuves : 17 mutations de l'auteur rouges ; la mutation de la revue restée verte remesurée à 0 rouge sure5662ad, puis 1 rouge sur0a9c9f7; vecteurs recalculés hors du code ; Rust 151 → 168, vitest 1311 → 1314 ; CI lue dans les logs sur les deux têtes (runs 441 à 444). Non gardé par les tests : le câblage des commandes à l'identifiant réel du poste, d'où la vérification manuelle. Acquis : mockito sert le premier mock correspondant qui attend encore des hits, donc un mockexpect(0)posé à côté d'un mock valide ne prouve rien ; un seul mock avecmatch_request. Merge par l'API enfast-forward-onlyépinglé sur la tête, branche supprimée. Aucune migration DB (v1→v17). (ref #350, PR #366, maximus-api#82, la-compagnie-maximus#184)
Blockers actifs
- Aucun blocker externe dur.
spec-monetisationfermé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
3673d09de maximus-api, URLcs_live_vérifiée), puis achat réel de contrôle le 2026-09-30 : clé sur/merciet par courriel, activation dans l'app, remboursement complet et licence révoquée parcharge.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 milestonespec-paiementsde 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 enstatus: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). Reste l'étape 10 de/releasesous Windows (Michel). - Vérifications post-merge de #390 (PR #394, sur le prochain build) : la case 5 se coche après un classement manuel ; sous Linux, un vrai profil secondaire ancien affiche « database updated with versions … » au Journal, sa copie est dans
~/.config/com.simpl.resultat/migration-backups/et l'import y fonctionne ; supprimer un profil retire son.db; les rendements du Bilan s'affichent. #390 reste enstatus:blockedjusque-là. - Vérifications manuelles dues sur la v0.17.0 publiée (onboarding + suites de licence ; 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.pyrend64 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). - Vérifications manuelles dues sur la prochaine release : parcours de démarrage guidé (#396 à #401, milestone
planned-2026-10-06-onboarding-parcours-guide), d'abord sous Linux avec Orca, puis sous Windows avec NVDA : les sections « Parcours guidé » dedocs/qa-onboarding.html(profil neuf de bout en bout, bandeau et liste, « Passer » et « Reprendre », règle D9 sur un vrai profil ancien, édition Gratuite à 5/5, contour dans WebKitGTK et WebView2, mouvement réduit, clavier et anneau de focus du contrôle entouré, annonces, et les limites connues renvoyées par les revues). Le même build sert aux vérifications post-merge de #390. #401 se ferme au merge ; la liste de la phase 1 pour la v0.17.0 reste lisible pargit show v0.17.0:docs/qa-onboarding.html. - Backlog ouvert : vague
planned-2026-09-24-paiementsclose 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-resultaten prod). #365 fermée le 2026-10-03 après sa vérification manuelle. Milestoneplanned-2026-10-03-suites-licencefermée 3/3 le 2026-10-05 (#373, #370, #367 mergées, voir Décisions ; suivi #389 enstatus:triage). Hors milestone, enstatus: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 dans3673d09, 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/pricesne 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-paiementsreste le parapluie des trois dépôts (ici 4/5, reste #363) ; onboarding phase 2 (parcours guidé) mergée : milestoneplanned-2026-10-06-onboarding-parcours-guidefermée 6/6 le 2026-10-08 (#396 à #401,ee17f31), suivis #408 et #409 (status:triage) ; onboarding phase 1 livrée : milestoneplanned-2026-10-03-onboarding-phase1fermé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 dansdocs/analyse-onboarding-2026-09.md, plan détaillé dans lesspec-*-onboarding-phase1.mdlocaux, ignorés par git ; #271 absorbé par #301, livré ;spec-ci-build-optimizationfermé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 (status:triage: Node 20, en fin de vie depuis le 2026-04-30, encore installé parcheck-frontend.ymletaudit.yml, et commentaireconcurrencydecheck-rust.ymldémenti parforgejo-ops.mdpour les runs de PR). Le suivi « globsrc-tauri/**non prouvé » ouvert avec #232 est levé : la PR #344 est le cas test isolé attendu (Cargo.lock+ 2.mdseulement) —check-rusta bien tourné,check-frontenda 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», oraudit.ymltire tous les jours à 06:00 UTC (19 runsscheduleverts 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.tomlest bien lu en conteneur surmain— l'ADR 0018 ne l'avait vérifié que par unworkflow_dispatchsur une branche. #343 fermée le 2026-09-04 (PR #344) — RUSTSEC-2026-0258 surh2, la seule vulnérabilité qui rougissait l'audit depuis le 08-19 ; l'audit est de nouveau vert surmain, prouvé parworkflow_dispatch(run 393) et non déduit du run de PR. #348 fermée le 2026-09-21 (PR #349) — RUSTSEC-2026-0285 surrustls, seule vulnérabilité rougissant l'audit depuis le 09-15 (7 runs, 405→411) ; vert reprouvé parworkflow_dispatchsurmain(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-dom7.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 pourrsa, désormais seule entrée de.cargo/audit.toml— le garde-fou est passé à 2 vérifications) et #345 (domicilier la contraintewindows-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 quelcargo update» mais tout bump atteignant le sous-arbre réseau/TLS — mesuré :-p anyhowne bouge rien,-p hyperfait 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 àhyperet à 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 dewindows-sysplutô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 dewindows-syscompilé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-rss'arrête surlib.exe, il faudraitcargo-xwin). Côté npm, #358 ouverte le 2026-09-26 par/analyse-vulnerabilite:npm auditremonte 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 avecnpx npm@11(npm 10 plante sur un bump de vitest 4.1.x). - Nouveau bug ouvert : #320 — les installations
.rpmne reçoivent aucune mise à jour (latest.jsonne porte qu'une entréelinux-x86_64construite depuis le.deb,release.yml:104-122), alors que les.rpmcontinuent d'être publiés en assets. Documenté en §3 dedocs/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 dansCLAUDE.mdetdocs/architecture.md(composants, pages, services,Version actuelle : 0.6.3vs 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.0 (2026-10-05) ;[Unreleased]vide.