@eqs/cli : doctor, inspect, baseline — l'audit observé, jamais déclaré #11

Merged
nicolas-fryder merged 1 commit from feat/cli into main 2026-09-07 08:23:28 +00:00

ROADMAP #10, le dernier package du socle. Les dix packages sont écrits.

eqs doctor ne réimplémente aucun contrôle

Il charge ceux des packages installés dans le dépôt inspecté, résolus depuis lui : un satellite resté sur @eqs/auth@1.1 est jugé par les contrôles de sa version, pas par ceux d'une version qu'il n'a pas. Le contexte qu'il leur passe ne contient que la racine — tout ce qui exige l'application démarrée se déclare « contrôle non exécutable » (les packages le disent déjà eux-mêmes) et se compte à part, jamais confondu avec un succès.

Deux règles tiennent eqs-audit.json

Règle Pourquoi
Chaque champ a une source dans SOURCES qui sait échouer, et cli.champ-observe refuse un champ qui n'y est pas Sans lui, un champ ajouté « en attendant » se remplit d'une constante, personne ne le revoit, et Topologie agrège une flotte de vœux
Ce qui n'a pas été mesuré vaut null, jamais false, avec sa raison dans nonObserve Un false inventé se lit comme un constat, et c'est ainsi qu'un audit devient un document de complaisance

C'est l'écart au cahier le plus visible : api.errorFormat, api.runtimeValidation et observability.* sortent à null en statique, en disant qu'ils demandent runConformance. outgoing.rawHttpCalls vaut null — et non 0 — quand @eqs/http n'est pas installé : personne n'a compté.

Les dispenses

Motif de MCP/scripts/audit.mjs, qui existe parce que npm audit ne sait pas accepter une alerte précise : son seul geste est de baisser le seuil, ce qui éteint la porte entière pour une alerte. Quatre façons d'échouer : le bloquant non dispensé ; la dispense périmée (une dispense sans fin est une porte retirée en douce) ; la dispense qui ne couvre plus rien (le problème est corrigé, elle survit en couvrant potentiellement autre chose) ; et celle qui ne dit ni pourquoi, ni jusqu'à quand, ni par qui.

Preuves

  • 65 tests. Les cinq contrôles contre un dépôt conforme et un dépôt fautif, dont le test négatif que le cahier exige nommément : une dispense datée d'hier.
  • Sur de vrais dépôts, pas seulement des fixtures : eqs migrate inspect sur ATLAS non rétrofitté rend profile: next-fullstack (le critère du cahier §9), 81 fichiers de test unitaires, 4 d'intégration, 13 e2e, hooks branchés, gitleaks 8.30.1 ; MCP/apps/api rend profile: nest ; eqs migrate plan sur ATLAS liste les dix étapes avec les fichiers que chaque package remplacerait.
  • pnpm check vert à la racine : 280 tests sur les dix packages.

Corrigé au passage

@eqs/testing n'émettait pas ses déclarations de types. tsconfig.base.json ne pose pas declaration — il sert aussi aux applications, qui n'ont personne à typer — et le manifeste annonçait des .d.ts que la construction ne produisait pas : tout consommateur voyait le package en any sans que le compilateur le dise. @eqs/cli, son premier consommateur, l'a révélé. Changeset patch joint.

Ce qui n'est pas fait, et pourquoi

  • data.* n'a aucun contrôle source : il demande la lecture du schéma de données, reportée avec le rétrofit (#15).
  • tests.conformance lit .eqs/conformance.json, que runConformance n'écrit pas encore : il faudrait que les harnais de profil rendent leurs problèmes au lieu de les jeter dans un expect. Reporté avec le template (#11).
  • Le validateur de schéma est un sous-ensemble maison, qui échoue sur un mot-clé qu'il ne sait pas appliquer — plutôt qu'une dépendance de plus pour valider notre propre schéma. Le fichier publié reste du JSON Schema valide : Topologie l'ingère avec un vrai validateur.

Écarts au cahier détaillés dans le champ Statut de packages/cli/CAHIER-DES-CHARGES.md.

🤖 Generated with Claude Code

ROADMAP #10, le dernier package du socle. **Les dix packages sont écrits.** ## `eqs doctor` ne réimplémente aucun contrôle Il charge ceux des packages installés **dans le dépôt inspecté**, résolus depuis lui : un satellite resté sur `@eqs/auth@1.1` est jugé par les contrôles de sa version, pas par ceux d'une version qu'il n'a pas. Le contexte qu'il leur passe ne contient que la racine — tout ce qui exige l'application démarrée se déclare « contrôle non exécutable » (les packages le disent déjà eux-mêmes) et se compte à part, jamais confondu avec un succès. ## Deux règles tiennent `eqs-audit.json` | Règle | Pourquoi | | --- | --- | | Chaque champ a une source dans `SOURCES` qui sait échouer, et `cli.champ-observe` refuse un champ qui n'y est pas | Sans lui, un champ ajouté « en attendant » se remplit d'une constante, personne ne le revoit, et Topologie agrège une flotte de vœux | | Ce qui n'a pas été mesuré vaut `null`, **jamais `false`**, avec sa raison dans `nonObserve` | Un `false` inventé se lit comme un constat, et c'est ainsi qu'un audit devient un document de complaisance | C'est l'écart au cahier le plus visible : `api.errorFormat`, `api.runtimeValidation` et `observability.*` sortent à `null` en statique, en disant qu'ils demandent `runConformance`. `outgoing.rawHttpCalls` vaut `null` — et non `0` — quand `@eqs/http` n'est pas installé : personne n'a compté. ## Les dispenses Motif de `MCP/scripts/audit.mjs`, qui existe parce que `npm audit` ne sait pas accepter une alerte précise : son seul geste est de baisser le seuil, ce qui éteint la porte entière pour une alerte. Quatre façons d'échouer : le bloquant non dispensé ; la dispense périmée (une dispense sans fin est une porte retirée en douce) ; la dispense qui ne couvre plus rien (le problème est corrigé, elle survit en couvrant potentiellement autre chose) ; et celle qui ne dit ni pourquoi, ni jusqu'à quand, ni par qui. ## Preuves - 65 tests. Les cinq contrôles contre un dépôt conforme **et** un dépôt fautif, dont le test négatif que le cahier exige nommément : une dispense datée d'hier. - **Sur de vrais dépôts, pas seulement des fixtures** : `eqs migrate inspect` sur ATLAS non rétrofitté rend `profile: next-fullstack` (le critère du cahier §9), 81 fichiers de test unitaires, 4 d'intégration, 13 e2e, hooks branchés, gitleaks 8.30.1 ; `MCP/apps/api` rend `profile: nest` ; `eqs migrate plan` sur ATLAS liste les dix étapes avec les fichiers que chaque package remplacerait. - `pnpm check` vert à la racine : 280 tests sur les dix packages. ## Corrigé au passage **`@eqs/testing` n'émettait pas ses déclarations de types.** `tsconfig.base.json` ne pose pas `declaration` — il sert aussi aux applications, qui n'ont personne à typer — et le manifeste annonçait des `.d.ts` que la construction ne produisait pas : tout consommateur voyait le package en `any` sans que le compilateur le dise. `@eqs/cli`, son premier consommateur, l'a révélé. Changeset `patch` joint. ## Ce qui n'est pas fait, et pourquoi - `data.*` n'a aucun contrôle source : il demande la lecture du schéma de données, reportée avec le rétrofit (#15). - `tests.conformance` lit `.eqs/conformance.json`, que `runConformance` n'écrit pas encore : il faudrait que les harnais de profil rendent leurs problèmes au lieu de les jeter dans un `expect`. Reporté avec le template (#11). - Le validateur de schéma est un sous-ensemble maison, qui **échoue** sur un mot-clé qu'il ne sait pas appliquer — plutôt qu'une dépendance de plus pour valider notre propre schéma. Le fichier publié reste du JSON Schema valide : Topologie l'ingère avec un vrai validateur. Écarts au cahier détaillés dans le champ **Statut** de `packages/cli/CAHIER-DES-CHARGES.md`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Avec trente dépôts, regarder l'état de chacun à la main est impraticable. Les
gates existaient (MCP, nuage, ATLAS) mais chacune sortait son propre texte :
rien n'était agrégeable, et personne ne pouvait voir « qu'est-ce qui a changé »
par rapport à l'état accepté.

`eqs doctor` ne réimplémente aucun contrôle : il charge ceux des packages
installés DANS LE DÉPÔT INSPECTÉ, résolus depuis lui — un satellite resté sur
@eqs/auth@1.1 est jugé par les contrôles de sa version, pas d'une version qu'il
n'a pas. Le contexte qu'il leur passe ne contient que la racine ; tout ce qui
exige l'application démarrée se déclare « contrôle non exécutable » et se
compte à part, jamais confondu avec un succès.

Deux règles tiennent `eqs-audit.json`. Chaque champ a une source dans SOURCES
qui sait échouer, et le contrôle `cli.champ-observe` refuse un champ qui n'y
est pas : sans lui, un champ ajouté « en attendant » se remplit d'une constante
et Topologie agrège une flotte de vœux. Et ce qui n'a pas été mesuré vaut
`null`, jamais `false`, avec sa raison dans `nonObserve` — un `false` inventé
se lit comme un constat.

Les dispenses reprennent `MCP/scripts/audit.mjs`, qui existe parce que
`npm audit` ne sait pas accepter une alerte précise. Quatre façons d'échouer :
le bloquant non dispensé, la dispense périmée (une dispense sans fin est une
porte retirée en douce), la dispense qui ne couvre plus rien, et celle qui ne
dit ni pourquoi, ni jusqu'à quand, ni par qui.

65 tests, dont les cinq contrôles contre un dépôt conforme et un dépôt fautif,
et le test négatif que le cahier exige : une dispense datée d'hier. Vérifié sur
de vrais dépôts : `eqs migrate inspect` sur ATLAS non rétrofitté rend
`profile: next-fullstack`, 81 fichiers unitaires, 4 d'intégration, 13 e2e,
gitleaks 8.30.1 ; `MCP/apps/api` rend `profile: nest`.

Corrigé au passage : @eqs/testing n'émettait pas ses déclarations de types.
Son manifeste annonçait des .d.ts que la construction ne produisait pas, et
tout consommateur le voyait en `any` sans que le compilateur le dise. @eqs/cli,
son premier consommateur, l'a révélé.

Les dix packages du socle sont écrits.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nicolas-fryder deleted branch feat/cli 2026-09-07 08:23:28 +00:00
Sign in to join this conversation.
No reviewers
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!11
No description provided.