24 KiB
STATE — Simpl'Résultat
Derniere MAJ : 2026-07-18 (v0.14.0 shippée — milestone
planned-2026-07-15-collapse-multi-niveaux4/4 : repli des catégories à chaque niveau sur les 3 rapports hiérarchiques + grille Budget + unification des 2 arbres de catégories, persistance par-profil viauser_preferences(ADR 0016). Pile de 4 PRs #292-#295 →/pr-reviewAPPROVE ×4, ff-merge (main5a3d87b), tagv0.14.0(9c18e10) → CI release #322. Auparavant cette session : v0.13.0 taggée (2026-07-13) — le backlog[Unreleased]accumulé depuis v0.12.0 (filtres de comptes #272-#279, tendances hiérarchiques #262-#265, collapse niveau-1 #254). 828 vitest + 98 Rust. Aucune migration DB (v1→v16). #259 (fusion catégories custom en migration) restestatus:ready, non exécutée)
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). 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.
Decisions recentes
- 2026-07-18 : Milestone collapse multi-niveaux (#288-291) livrée → v0.14.0. Cycle complet en une session :
/plan-run(spec 2 fichiers, 8 décisions drainées) →/review-spec(3 experts, verdict 🔴) → refonte v2 →/autopilot(4 workers) →/pr-review×4 → ff-merge → release. Le point clé : la revue a tué l'algo v1. Il suivait un curseur de profondeur supposant un ordre DFS ; or la grille Budget (useBudget.ts:361) trie par niveau — les 3 experts l'ont trouvé indépendamment. Refonte v2 : visibilité par remontée deparent_id(une ligne visible ssi tous ses ancêtres dépliés), order-independant → résout d'un coup l'ordre budget, le tri par type qui sépare parent/enfant, la feuille « (direct) » qui partage la clé du parent, et la contraintevisible()-avant-reorderRows. Pile linéaire forcée (B/C/D dépendent tous du nouveau hook de A → pas de wave parallèle) : PRs #292-#295, chacune basée sur la précédente./pr-reviewAPPROVE ×3 + 1 REQUEST_CHANGES (#295 : ligne- Spec:de l'ADR 0016 pointant des specs gitignorées → 404 ; corrigé par force-add des specs à la racine, précédent repospec-refonte-rapports.md; au passage la revue s'est trompée en disant que 0015 n'avait pas de ligne Spec — elle en a une, cassée pareil, bug pré-existant signalé). ff-merge de la pile (4 issues auto-fermées viaResolves #N, milestone 4/4, 4 branches supprimées) → v0.14.0 taggée. Persistance migréelocalStorage→user_preferences(base du profil) :deleteProfilene purge aucunlocalStorage→ une clé par-profil y serait un résidu survivant à la suppression, révélant les catégories explorées d'un profil PIN-protégé (exigence privacy-first, ADR 0016, frontière tracée : état UI par-profil → DB profil, état UI machine → localStorage). Le hook gagnedefaultExpanded+storageKeynullable, qui unifie aussi les 2 arbres de catégories (#290 :CategoryTreedéplié-par-défaut, guide replié ; corrige le bugallExpanded = size>0du guide ; worker a trouvé un 4e consommateurStepDiscovernon listé au plan, migré). 828 vitest, aucune migration DB. Écarts protocole tracés au rapport : workers auto-validés sans forker/pr-review(évite le double-post feedback-pr-review-subagent-forks) ; #294 sans test (refactor de rendu, non testable sans jsdom) → vérif runtime déléguée à la revue. Restespec-ci-build-optimization(2/4) +spec-paiements(#270/#271) + #259. (ref #288-291, PRs #292-#295) - 2026-07-12 : #259 recadrée — l'issue décrivait un flux qui n'existe pas (rectifie les entrées des 2026-07-05 / 07-11 qui la classaient « mapping manuel compte sans similaire auto » et « reliquat de l'epic #260 » : les deux sont faux). Le corps d'origine, rédigé à chaud le 2026-07-05 pendant le run v0.12.0, avait transposé par analogie le signalement de Max vers le module Bilan sans ouvrir le fichier : il décrivait une auto-association des comptes standards aux comptes existants du profil dans
StarterAccountsModal, avec « case désactivée quand aucun similaire n'est auto-identifié ». Aucune notion de mapping n'existe dans ce flux — la case est un simple « créer ce compte : oui/non », désactivée quand une collision EST détectée (StarterAccountsModal.tsx:160), soit la polarité inverse ; le commentairel.8cité (« the matching checkbox ») désignait « la case correspondante », pas « la case de matching ». Le vrai sujet (confirmé par Max) est la migration des catégories :computeMigrationPlanrange les catégories en 2 seaux et un seul est éditable —plan.rows(seed) passe par le moteur d'appariement + type-ahead par ligne (#246/#252), tandis queplan.preserved(catégories custom) est poussé avecv1TargetId: nullsans même être soumis au moteur d'appariement, rendu en<li>texte brut (StepSimulate.tsx:202-216, aucun picker) et déversé d'office par le writer sous le fourre-tout « Catégories personnalisées (migration) ». Sémantique tranchée avec Max : fusion (choisir une feuille standard réassigne tx/budgets/mots-clés/fournisseurs et fait disparaître la custom ; ne rien choisir = comportement actuel, et ne doit pas bloquer le bouton « Suivant »). Re-parentage écarté. Travail = câblage sur 3 couches (UIStepSimulate→MappingRowréutilisable tel quel ; reducerRESOLVE_ROWqui ne voit queplan.rows; 4 retouches du writer) — la machinerie de fusion est déjà générique (buildMappingFromRowsfiltre les cibles nulles, étapes 3-7 bouclent sur la Map). Complexité Medium. Piège à couvrir : fusionner une custom parente ayant des enfants custom (listepreservedplate → l'enfant non résolu retombe au fourre-tout, pas d'orphelin, mais aucun test ne le garantit). Leçon process : une issue rédigée par analogie en fin de run, sans lecture du code, peut inverser la prémisse et se tromper de module — le/analyzel'a rattrapée 6 jours plus tard. (ref #259) - 2026-07-11 : M2 « rapports-parite » (#277-#279) shippée — dernière grosse tranche de l'epic #260 « rapports uniformes ». Run
/autopilot(3 workers en worktree → PRs #285/#286/#287), reviewée via 3/pr-reviewadversariales parallèles (read-only,git showsans checkout) : APPROVE #285 (grille budget income-first, #278) + APPROVE #286 (BVA réel-vs-budget income-first, #277) + REQUEST_CHANGES #287 (dashboard Cartes, #279). Blocage #287 = le point I7 prédit au plan confirmé réel :getCartesSnapshotpropageaitaccountIdsaux sous-rapports top-movers/budget mais pas aux sériesfetchMonthlyFlows(KPIs/sparklines/overlay 12 mois) nifetchSeasonality→ sur le dashboard (1re page à exposer le filtre par-dessus ces séries) les KPI montraient des totaux non filtrés à côté de barres/tendance filtrées. Fix (9ee5ad3) : threaderaccountIds?dans les 2 fetchers (source_id IN (...)paramétré viainPlaceholders, index$3/$4) + câblagegetCartesSnapshot; le CHANGELOG #279 promettait déjà le filtrage → code aligné sur la promesse, texte inchangé ; +2 assertions cartes. Merge local de la pile (3 merges--no-ff, conflit additif CHANGELOG ×2 résolu par union #277/#278/#279 — i18n non conflictuel car #277/#278 réutilisent des clés existantes, seul #279 touche les locales ; STATE non conflictuel car branches ne l'ont pas commité) → tip cumulé validé (tsc + vite build + 811 vitest + cargo check + 98 Rust) → pushmaina982f9e. Réconciliation Forgejo : 3 issues auto-fermées viaResolves #N, 3 PRs fermées manuellement (merges locaux non détectés merged), milestoneovernight-2026-07-08-rapports-parite3/3 fermée, branches supprimées, worktrees leftover nettoyés (gotcha recursion). Aucune migration DB (v1→v16), non taggé ([Unreleased]). Wrinkle process : le fork du skill/pr-reviewavait posté un APPROVE prématuré sur #287 (I7 gradé non bloquant) → superséé + commentaire stale supprimé par la passe adversariale indépendante (trace code + « 1re page à exposer le filtre » + CHANGELOG à honorer) ; valeur de la double-vérif indépendante. Suivi non bloquant :getDashboardSummary= code mort à retirer. Reste de #260 : #259 (mapping manuel compte sans similaire auto). (ref #260, #277-#279, PRs #285-#287) - 2026-07-08 : Suite #260 — M1 « filtres-fondation » mergée (
mainfe9ae01), M2 prête. Planifiée via/plan-overnight+/review-spec(filtre multi-comptesaccountIds[]/IN(...)tranché après analyse, révise le « sourceId singulier » initial). M1 livrée via/autopilot(5 workers séquentiels en worktree → PRs #280-#284 en pile linéaire) +/pr-reviewAPPROVE ×5 + merge local fast-forward : hookuseReportsPeriodadditif (+accountIdsURLsources+ typeReportFilters, #272), 7 services enaccountIds[]via helper paramétrésqlFilters.inPlaceholders(#273),<FilterPanel>slot temporel + multi-select « sources d'import » (libellé distinct du Bilan, #274), adoption Tendances (#275) + Compare/Budget (#276 — incl.CompareBudgetView; câblage budget viagetActualTotalsForYear, le body citait à tortgetBudgetVsActualData). Aucune migration DB. Build + 791 vitest verts (728 + 63). NB : le « 4676 / 277 fichiers » vu en pré-merge était une pollution de worktrees —vitestrécursait dans les 5 worktrees leftover sous.claude/worktrees/(791 × ~6) ; nettoyés depuis, compteur réel = 791. Gotcha : nettoyer les worktrees (ou exclure.claude/worktrees/) avant de valider un tip. Réconciliation Forgejo complète (5 issues auto-fermées viaResolves #N, 5 PRs fermées, milestone fermée, branches supprimées ; worktrees nettoyés). M2overnight-2026-07-08-rapports-parite(#277-#279) prête →/autopilot(BVA + grille budget income-first + dashboard Cartes). Notes review pour M2 : sériesgetCartesSnapshot(fetchMonthlyFlows/fetchSeasonality) non filtrées (I7/#279) ; grille budget câblée viagetActualTotalsForYear. (ref #260, #272-#276, PRs #280-#284) - 2026-07-07 : Tendances hiérarchiques livrées (1re slice de l'epic #260 « rapports uniformes »). Préparée via
/plan-overnight(13 décisions drainées ;/review-spec3 experts → 3 critiques résolus par l'approche sidecar : garder le pivot par mois pour chart + dashboard (DashboardPage:142= consommateur partagé oublié), ajouter un arbre clé-par-id pour le tableau — pivot clé-par-nom aurait faussé le Résultat net sur homonymes une fois leLIMIT 50retiré), puis exécutée le même jour via/autopilot(session interactive, ciblée par nom de milestone hors fenêtre horaire — cf. mémoire feedback-plan-execute-temporal-decoupling). 4 workers en worktree → issues #262-#265,/pr-reviewAPPROVE ×4, merge local de la pile (#266 standalone + chaîne #267→#268→#269 ; CHANGELOG auto-résolu par section, vérifié) ; tip cumulé validé build + 728 vitest → pushmainfe87313, réconciliation Forgejo (4 PRs fermées, 4 issues auto-fermées viaResolves #N, milestoneovernight-2026-07-08-tendances-hierarchiquesfermée, branches supprimées). Contenu : tendance par catégorie → tableau income-statement hiérarchique + collapse replié-par-défaut (défaut byCategory+table = fix « paie invisible »),getCategoryOverTimeen arbre id-keyed sidecar viabuildLeafDrivenTree<T>générique extrait debuildCompareTree(behavior-preserving), Résultat avant transferts interleavé. Aucune migration DB, non taggé ([Unreleased]). 2 polish non bloquants : perf dashboard (arbre construit non lu, #264), DRYtypeOfdupliqué (#265). Reste de #260 (BVA-au-standard, budget, dashboard, filtres partagés) différé. (ref #260, #262-#265, PRs #266-#269) - 2026-07-07 : #254 (collapse/expand des sous-catégories) livré + #258 (db-locked) fermé. #254 : chevron par catégorie parente + « tout replier/déplier » sur les 2 rapports comparables hiérarchiques (
ComparePeriodTableréel-vs-réel,BudgetVsActualTableréel-vs-budget) ; repli par défaut (contrainte remontée de #260), état persisté par rapport en localStorage. Repli purement visuel — sous-totaux/totaux/résultats calculés sur les lignes brutes, jamais les visibles (tracé en /pr-review). ModulecollapsibleRows.ts(pur) + hookuseCollapsibleGroups.ts+ 12 tests → 713 vitest, aucune migration DB.CategoryOverTimeTableexclu (liste plate top-N, rien à replier) → relève de l'epic #260. Livré via sous-agent en worktree isolé + /pr-review APPROVE + merge API (single PR, pas de conflit i18n/CHANGELOG) → PR #261, #254 auto-fermée. #258 fermé comme déjà corrigé en v0.10.1 (8cb7e53, présent v0.11.0/v0.12.0) : la piste « BEGIN imbriqué » du body était une mauvaise lecture —withTransaction(db.ts) n'émet aucun BEGIN,proposeStarterAccountsInTransaction:720est le seul (même pattern quesaveSnapshotAtomic/upsertSnapshotLinesqui ne deadlockent jamais) ; smell latent noté (gardeinTransaction= booléen global, pas un compteur → requête simple concurrente pendant une transaction bypasse le verrou). Prochaine étape : /plan-overnight de l'epic #260. (ref #254/#258, PR #261) - 2026-07-05 : v0.12.0 shippée (tag
v0.12.0→ CI release #311). Compare réel-vs-réel (#253) + tableau de tendance par catégorie (#256) refondus en analyse de résultat : revenu affiché, Résultat avant transferts (revenus − dépenses) + Résultat net (après transferts), sections revenu→dépense→transfert ; rapports comparables par défaut au mois complet précédent (#253). Origine : #243 (montants de transfert inclus dans le comparable) recadré par Max en « voir si je suis over/under ». Livré en 2 issues/PRs stackées #255→#257 (merge local + réconciliation Forgejo, PRs fermées, branches supprimées). Modules purscompareResults.ts/overTimeResults.tstestés ; 2 blocages/pr-reviewcorrigés (fuite du revenu dans les top-movers Cartes viaCOMPARE_DELTA_SQLélargi income+transfer → filtre expense-only + régression ; garde StrictMode value-change sur le sync mois-réf,syncReferenceOnPeriodChangepur). 701 vitest verts, aucune migration DB. Ouvert au passage : #258 (db-lockedproposeStarterAccounts, probable BEGIN imbriqué danswithTransaction), #259 (mapping manuel compte sans similaire), #254 (collapse/expand). Suivi différé : aligner le placement « Résultat avant transferts » deCategoryOverTimeTable(bas) sur le compare (interleavé). (ref #253/#256, PRs #255/#257) - 2026-07-05 : Run
/autopilotsurovernight-2026-07-05-bilan-rapports-ux(préparée la veille via/analyze#243-#246 + split #247) → 5 issues livrées, PRs #248-#252 toutes/pr-reviewAPPROVE. Merge local de la pile (l'API merge échoue sur les conflits i18n/CHANGELOG garantis — 4 fichiers partagésfr.json/en.json/CHANGELOG.md/CHANGELOG.fr.md, voir mémoire reference-shared-conflict-files) ; réconciliation Forgejo (PRs fermées manuellement, issues auto-fermées viaResolves #N, milestone fermée) ; release v0.11.0 taggée. Validation locale du tip cumulé : build + 679 vitest + cargo verts (check.ymlne tourne ni sur pushmainni sur les bases non-maintype #249). Polish #252 post-review : picker migration feuilles-seulement + helpercomboboxCategoriesForTargettesté. (ref #243-#247, PRs #248-#252) - 2026-07-04 : Override
@babel/coremergé (issue #241, PR #242 — review /pr-review APPROVE + CI verte rust/frontend) — clôt le reliquat@babel/corelow du sprintdeps-security-2026-07. GHSA-4x5r-pxfx-6jf8 (arbitrary file read viasourceMappingURL, CVSS 3.2, dev/build-only via@vitejs/plugin-react) :npm audit fixinopérant (version pinnée par le parent → empile une copie sans résoudre), fix =overridesscopé{"@vitejs/plugin-react":{"@babel/core":"^7.29.7"}}→ patch 7.x non-breaking (7.29.0→7.29.7), arbre 109→109 (pas d'explosion),npm audit1→0. Build + 635 vitest verts. Détecté via /analyse-vulnerabilite — rapport VPS--freshinaccessible (auth navigateur Tailscale SSH en attente, jamais reçu le lien) →npm auditlive utilisé ; rapport local périmé (2026-05-06) portait 1 faux positifsecrets(« Generic Token Assignment » surbalance.service.ts, contenu disparu depuis la réécriture Bilan). Voir mémoire reference-analyse-vulnerabilite-inflation-transitive (ref #241, PR #242) - 2026-07-01 : Sprint
deps-security-2026-07livré (4/4, milestone fermée) via /sprint — 4 vulns Defenseur (2026-06-30) remédiées en 2 PRs séquentielles (fichier partagépackage.json→ pas de worktrees parallèles). PR A #239 :react-router-dom7.13→7.18.1 ferme #235 (racine, 7 advisories dont turbo-stream RCE) + #238 (0 CVE propre, héritage transitif — 1 bump du parent suffit,npm audit viaParents). PR B #240 :vite6.4.2→6.4.3 (#236) +vitest4.0.18→4.1.9 (#237), restés en 6.x/4.x (majors 8.x/latest écartés), 635 vitest verts (bump vitest 4.0→4.1 sans régression).npm audit5→1 ; reste@babel/corelow volontairement hors scope (npm audit fixajoute 77 paquets sans résoudre, pinné par parent → override scopé dédié à faire). Surface réelle faible (app Tauri desktop, pas de serveur SSR/RSC). Voir mémoire reference-analyse-vulnerabilite-inflation-transitive (ref #235-#238, PRs #239/#240)
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. - Backlog ouvert (
status:ready, non bloqué) :spec-paiements(#270 activation /v1 + product explicite + URL achat localisée ; #271 re-gate auto-update derrière la licence Base) ;spec-ci-build-optimization2/4 (#234 connectivité cache runner, #232 split workflows) ; #259 (fusion des catégories custom en migration de taxonomie).