Rétrofit d'un existant : le socle ne décrit aucun mécanisme de baseline, ni pour tsc (D-024 nomme l'intention, pas le moyen) ni pour ESLint (1 474 violations mesurées sur ATLAS) #85

Closed
opened 2026-09-21 08:09:12 +00:00 by nicolas-fryder · 0 comments

Ce qui manque

Adopter @eqs/tooling sur un dépôt qui a deux ans de code coûte, mesuré sur ATLAS (292 fichiers TypeScript, @eqs/tooling 0.12.1) :

outil résultat à l'adoption
tsconfig.next.json 1 028 erreurs dans 261 fichiers — 753 noUncheckedIndexedAccess (TS18048/TS2532), 89 exactOptionalPropertyTypes (TS2375/TS2379), le reste des undefined non assignables qui en découlent. 588 sous tests/.
next() d'@eqs/tooling/eslint 1 474 violations dans 212 fichiers — no-unsafe-member-access 536, no-unsafe-assignment 278, eqeqeq (mode always) 179, consistent-type-imports 103 (auto-corrigible), no-base-to-string 89, no-misused-promises 73, require-await 61.

Le cahier de @eqs/tooling §4 dit : « une règle désactivée localement se fait par commentaire justifié dans le fichier, jamais en surchargeant ces jeux ». Mille quatre cents commentaires ne sont pas une baseline, c'est du bruit. Et D-024 dit qu'un dépôt rétrofitté « pose une baseline d'erreurs TypeScript, par dossier, dans son propre tsconfig » — mais TypeScript ne sait pas relâcher un drapeau par dossier. La décision nomme l'intention et pas le moyen.

Ce qu'ATLAS a fait, et qui pourrait devenir la règle

tsc. Les deux drapeaux restent actifs sur src/, prisma/, scripts/ et worker/ (les 440 erreurs s'y corrigent pour de vrai — ce sont des accès undefined qui atteignaient des requêtes). tests/ porte un second projet, tests/tsconfig.json, qui étend la racine et relâche les deux drapeaux, avec la date et le chiffre dans un commentaire ; le projet racine l'exclut, et une tâche types-tests de la porte le joue (voir le ticket sur eqs check, qui n'a pas de moyen de la déclarer). Résultat : 0 erreur sous tests/ avec la baseline, et « retirer une ligne du tsconfig fait apparaître ce qui reste » — c'est un cliquet lisible.

ESLint. Les suppressions natives d'ESLint ≥ 9.24 (--suppress-all écrit eslint-suppressions.json ; une violation nouvelle échoue ; une violation corrigée fait échouer aussi tant que --prune-suppressions n'a pas été joué). Aucune règle du socle n'est retirée du eslint.config.mjs, le fichier de suppressions ne peut que rétrécir, et il se lit règle par règle — exactement la forme des dispenses d'eqs doctor, mais tenue par l'outil lui-même.

Ce que je proposerais

  1. D-024 : écrire le mécanisme — second projet TypeScript pour les dossiers qu'on ne tient pas, joué par la porte — plutôt que « dans son propre tsconfig », qui laisse croire à une option par dossier qui n'existe pas.
  2. Cahier @eqs/tooling §4 : nommer les suppressions natives d'ESLint comme LE mécanisme de baseline d'un rétrofit, avec la règle du cliquet (--prune-suppressions obligatoire après correction, jamais --pass-on-unpruned-suppressions).
  3. eqs doctor pourrait lire eslint-suppressions.json et le compter comme les dispenses : un fichier qui grossit d'une sortie à l'autre est un écart, et une suppression non purgée est une dispense périmée.
  4. Au passage : le contrôle tooling.eslint-etend conseille import { nest } from '@eqs/tooling/eslint' à un dépôt dont eqs.profile vaut next-fullstack. Le message pourrait lire le profil.

Versions

@eqs/tooling 0.12.1, @eqs/cli 0.12.1, ESLint 9.39.5, TypeScript 5.9.3, pnpm 11.8.0, Node 24.15.0, Windows 11. Contexte : rétrofit d'ATLAS, branche epic/retrofit de EQS/ATLAS, docs/retrofit-eqs.md (étape 1) ; plan détaillé dans docs/superpowers/plans/2026-09-21-retrofit-etapes-0-1-pnpm-tooling.md.

## Ce qui manque Adopter `@eqs/tooling` sur un dépôt qui a deux ans de code coûte, mesuré sur ATLAS (292 fichiers TypeScript, `@eqs/tooling` 0.12.1) : | outil | résultat à l'adoption | |---|---| | `tsconfig.next.json` | **1 028 erreurs** dans 261 fichiers — 753 `noUncheckedIndexedAccess` (TS18048/TS2532), 89 `exactOptionalPropertyTypes` (TS2375/TS2379), le reste des `undefined` non assignables qui en découlent. 588 sous `tests/`. | | `next()` d'`@eqs/tooling/eslint` | **1 474 violations** dans 212 fichiers — `no-unsafe-member-access` 536, `no-unsafe-assignment` 278, `eqeqeq` (mode `always`) 179, `consistent-type-imports` 103 (auto-corrigible), `no-base-to-string` 89, `no-misused-promises` 73, `require-await` 61. | Le cahier de `@eqs/tooling` §4 dit : « une règle désactivée localement se fait par commentaire justifié dans le fichier, jamais en surchargeant ces jeux ». Mille quatre cents commentaires ne sont pas une baseline, c'est du bruit. Et D-024 dit qu'un dépôt rétrofitté « pose une baseline d'erreurs TypeScript, par dossier, dans son propre tsconfig » — mais **TypeScript ne sait pas relâcher un drapeau par dossier**. La décision nomme l'intention et pas le moyen. ## Ce qu'ATLAS a fait, et qui pourrait devenir la règle **tsc.** Les deux drapeaux restent actifs sur `src/`, `prisma/`, `scripts/` et `worker/` (les 440 erreurs s'y corrigent pour de vrai — ce sont des accès `undefined` qui atteignaient des requêtes). `tests/` porte un **second projet**, `tests/tsconfig.json`, qui étend la racine et relâche les deux drapeaux, avec la date et le chiffre dans un commentaire ; le projet racine l'exclut, et une tâche `types-tests` de la porte le joue (voir le ticket sur `eqs check`, qui n'a pas de moyen de la déclarer). Résultat : 0 erreur sous `tests/` avec la baseline, et « retirer une ligne du tsconfig fait apparaître ce qui reste » — c'est un cliquet lisible. **ESLint.** Les **suppressions natives** d'ESLint ≥ 9.24 (`--suppress-all` écrit `eslint-suppressions.json` ; une violation nouvelle échoue ; une violation corrigée fait échouer aussi tant que `--prune-suppressions` n'a pas été joué). Aucune règle du socle n'est retirée du `eslint.config.mjs`, le fichier de suppressions ne peut que rétrécir, et il se lit règle par règle — exactement la forme des dispenses d'`eqs doctor`, mais tenue par l'outil lui-même. ## Ce que je proposerais 1. **D-024** : écrire le mécanisme — second projet TypeScript pour les dossiers qu'on ne tient pas, joué par la porte — plutôt que « dans son propre tsconfig », qui laisse croire à une option par dossier qui n'existe pas. 2. **Cahier `@eqs/tooling` §4** : nommer les suppressions natives d'ESLint comme LE mécanisme de baseline d'un rétrofit, avec la règle du cliquet (`--prune-suppressions` obligatoire après correction, jamais `--pass-on-unpruned-suppressions`). 3. **`eqs doctor`** pourrait lire `eslint-suppressions.json` et le compter comme les dispenses : un fichier qui grossit d'une sortie à l'autre est un écart, et une suppression non purgée est une dispense périmée. 4. Au passage : le contrôle `tooling.eslint-etend` conseille `import { nest } from '@eqs/tooling/eslint'` à un dépôt dont `eqs.profile` vaut `next-fullstack`. Le message pourrait lire le profil. ## Versions `@eqs/tooling` 0.12.1, `@eqs/cli` 0.12.1, ESLint 9.39.5, TypeScript 5.9.3, pnpm 11.8.0, Node 24.15.0, Windows 11. Contexte : rétrofit d'ATLAS, branche `epic/retrofit` de `EQS/ATLAS`, `docs/retrofit-eqs.md` (étape 1) ; plan détaillé dans `docs/superpowers/plans/2026-09-21-retrofit-etapes-0-1-pnpm-tooling.md`.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Infrastructure/eqs-platform#85
No description provided.