Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
977ef3a1d3
commit
bf02b267b1
1 changed files with 5 additions and 3 deletions
8
STATE.md
8
STATE.md
|
|
@ -1,8 +1,8 @@
|
|||
# STATE — Simpl'Résultat
|
||||
|
||||
> Derniere MAJ : 2026-10-12 (**#423 mergée (PR #428, `main` `8898213`) : les champs « Catégorie parente » et « Catégorie » du mot-clé passent au `CategoryCombobox` avec saisie.** Deux revues (REQUEST_CHANGES puis APPROVE), suivis appliqués en tête, merge ff par l'API. Suivi #429 (deux autres `<select>`, rognage dans `SplitAdjustmentModal`). Aucune migration (v1→v17).)
|
||||
> Derniere MAJ : 2026-10-13 (**Milestone `planned-2026-10-10-fiabilite-tests` mergée, 4/4 fermée — pile #433 → #436 en avance rapide par l'API, `main` `c17bf5d`, puis ADR 0024 poussé (`977ef3a`).** Verrou strict de `db.ts` (#408), harnais React partagé (#409), faux `t` unique et sa garde (#389), suivis du rattrapage des profils (#395). Suivis des revues appliqués en tête de pile sans nouvelle relecture, reste dans #437. Aucune migration (v1→v17).)
|
||||
>
|
||||
> Précédente MAJ : 2026-10-12 (**Milestone `planned-2026-10-10-release-deps` mergée, 4/4 fermée — pile #414 → #418 en avance rapide par l'API, `main` `9e8c41b`.** Node 24 dans `check-frontend`, `audit` et `release` (#376) ; garde `windows-sys 0.61.2` dans `check-rust` et ADR 0023 (#345) ; une clé `latest.json` par paquet Linux, sans clé générique `linux-x86_64`, retirée sur décision de Max (#320) ; lock npm rafraîchi, `npm audit` à 0 (#358, ferme #317) ; PR #418 de suivis des revues. Suivis de la revue de #418 en #419, dont un trou de la garde d'avant le `DELETE` à corriger avant le prochain tag.)
|
||||
> Précédente MAJ : 2026-10-12 (**#423 mergée (PR #428, `main` `8898213`) : les champs « Catégorie parente » et « Catégorie » du mot-clé passent au `CategoryCombobox` avec saisie.** Deux revues (REQUEST_CHANGES puis APPROVE), suivis appliqués en tête, merge ff par l'API. Suivi #429 (deux autres `<select>`, rognage dans `SplitAdjustmentModal`). Aucune migration (v1→v17).)
|
||||
|
||||
## Position actuelle
|
||||
|
||||
|
|
@ -34,8 +34,11 @@ Audit critique de la page Bilan livré (`docs/audit-bilan-2026-05.md`, revue CPA
|
|||
|
||||
**#423 mergée sur `main`** (2026-10-12, `8898213`, pas encore publiée) — les champs « Catégorie parente » (formulaire de catégorie) et « Catégorie » (dialogue « Nouveau mot-clé ») utilisent `CategoryCombobox` : saisie qui filtre, ordre hiérarchique, noms du seed traduits. Liste des parents : racines et niveau 1, moins la catégorie éditée, profondeur réduite de la hauteur de son sous-arbre (pas de 4ᵉ niveau), parent courant toujours gardé ; seule garde aujourd'hui, `updateCategory` ne vérifie rien (#393). Le dialogue mot-clé prend la liste des Transactions (actives et saisissables, D2) et ne garde la catégorie pré-remplie que si elle en fait partie. `[Unreleased]` porte un Modifié. Suivi : #429. Aucune migration (v1→v17).
|
||||
|
||||
**Fiabilité des tests et de `db.ts` mergée sur `main`** (2026-10-13, `c17bf5d`, pas encore publiée) — milestone `planned-2026-10-10-fiabilite-tests` fermée 4/4 (#408, #409, #389, #395 ; PRs #433 → #436 produites par `/autopilot` le 2026-10-12, relues par quatre `/pr-review` APPROVE, cinq commits de suivi en tête de pile) : `withTransaction` remet au rappel son propre handle, révoqué à la fin, toute autre requête attend derrière le verrou ; changement de profil en une seule section exclusive avec numéro de génération ; alerte Journal après 15 s d'attente ; harnais `src/test/hookHarness.ts` et faux `t` marqué `src/test/i18nMock.ts`, gardé par `src/__integration__/i18n-mock-guard.test.ts` ; le Journal nomme la copie d'un rattrapage arrêté et ne contient plus de chemin, une seule copie gardée par profil, la page d'erreur du démarrage disparaît quand le profil s'ouvre après le délai ; badge « non garanti » traduit. `[Unreleased]` porte un Modifié et deux Corrigé de plus. Suivi : #437. Aucune migration (v1→v17).
|
||||
|
||||
## Decisions recentes
|
||||
|
||||
- 2026-10-13 : **Milestone `planned-2026-10-10-fiabilite-tests` mergée — `/autopilot` (4 workers en série, 1 h 25, CI lue à chaque maillon) → quatre `/pr-review` APPROVE en parallèle → suivis en tête de pile → merge ff par l'API, chaque enfant reciblé sur `main` (`main` `c17bf5d`, 4 PRs `merged`).** Mesure du rattrapage : 306 ms en release pour 100 001 transactions (T490, NVMe), sous la règle des 3 s, donc `STARTUP_TIMEOUT_MS` reste à 10 000 (ADR 0021). Inventaire de #389 : 27 fichiers et non 24, trois mocks bruts venus de #423. Suivis appliqués en tête (`74fae14`, `a1c31a1`, `ac3a981`, `86eff9b`, `c17bf5d`), non relus : `close()` d'un ancien proxy rejeté, échec de fermeture consigné sans bloquer le changement de profil, `withoutFolders` qui ne laisse plus passer un dossier contenant une espace, garde i18n plus stricte, badge traduit. Tip éprouvé en worktree `npm ci` propre : sonde rc=1, tsc, build, 2065 vitest, 262 Rust. ADR 0024 (serveur MCP, Proposed) rebasé sur le merge puis poussé (`977ef3a`). **Acquis** : l'orchestrateur a d'abord contredit à tort un constat juste du worker (badge `best-effort` codé en dur), sur un `grep` tronqué par `head` ; ne jamais conclure à l'absence depuis une sortie tronquée. Aucune migration (v1→v17). (ref #408, #409, #389, #395, PRs #433-#436, #437)
|
||||
- 2026-10-12 : **#423 mergée (PR #428, `main` `8898213`) — menus déroulants de catégorie avec saisie dans le formulaire de catégorie et le dialogue mot-clé.** Issue créée et analysée le jour même (`/analyze` : types `Category` vs `CategoryTreeNode` incompatibles → type structurel `CategoryLike` sur le combobox ; le formulaire ne connaissait pas l'id édité → prop `editingId` ; deux listes différentes → **D2** de Max : liste des Transactions ; **D1** : #423 porte l'exclusion UI, #393 garde la validation service). Plan check refusé une fois (la liste `absolute` était rognée par le scrollport du dialogue, réglé en sortant les champs du bloc défilant). Première revue **REQUEST_CHANGES** : la règle ne regardait que les enfants directs, une racine avec petits-enfants pouvait recevoir un parent (4ᵉ niveau) ; corrigé par la hauteur du sous-arbre, test rouge d'abord sur la sonde du relecteur. Seconde revue **APPROVE**, quatre suivis appliqués en tête (`8898213`, non relu : commentaires #393 corrigés, garde de cycle épinglée, espions sur `buildParentOptions`, garde redondante retirée). Preuves : 1963 vitest, 9 mutations rouges de l'auteur (une survivante remplacée : la règle « descendance » était impliquée par la règle de profondeur), CI 526-528, worktree `npm ci` propre. **Acquis** : `/commits/<sha>/statuses` renvoie l'historique (`pending` puis `success`), lire `/commits/<sha>/status` agrégé ; `head_commit_id` du merge exige le SHA complet (409 « head out of date » sur un SHA court). Aucune migration (v1→v17). (ref #423, PR #428, #429, #393)
|
||||
- 2026-10-12 : **Milestone `planned-2026-10-10-release-deps` mergée — `/autopilot` (4 PRs stackées en 1 h 50, CI lue dans les journaux à chaque maillon) → quatre `/pr-review` APPROVE → PR #418 de suivis en tête de pile → `/pr-review` APPROVE → merge ff par l'API, chaque enfant reciblé sur `main` (`main` `9e8c41b`, 5 PRs `merged`).**
|
||||
- **Décision de Max : clé générique `linux-x86_64` retirée** de `latest.json`. Le worker de #320 puis la revue ont mesuré que ses seuls lecteurs (AppImage v0.4.3 à v0.4.5, binaire hors paquet) ne savaient pas installer le `.deb` qu'elle servait, et que les 64 tags qui embarquent l'updater (plugin 2.10.0) cherchent d'abord la clé de leur paquet : ces lecteurs reçoivent désormais `TargetsNotFound`, rien n'est installé.
|
||||
|
|
@ -78,7 +81,6 @@ Audit critique de la page Bilan livré (`docs/audit-bilan-2026-05.md`, revue CPA
|
|||
- 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)
|
||||
## 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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue