Le contrat OpenAPI généré ment sur les sessions et sur les erreurs, et le delta de baseline prend « non observé » pour une régression #167

Open
opened 2026-10-15 19:17:28 +00:00 by nicolas-fryder · 1 comment

Trouvé en lisant les journaux du fuzzing et de l'audit d'ATLAS (run 27, chasse 53). Les contrôles qui passaient sans regarder sont corrigés dans #166. Les points suivants demandent une conception.

Contrat (platform-next/src/server/openapi.ts)

  1. Le nom du cookie de session est écrit en dur : better-auth.session_token (l. 181). ATLAS a renommé ses cookies en atlas.*. Une authentification qui suit le contrat, comme le fuzzing derrière la porte (eqs-workflows), enverrait le mauvais cookie. → OptionsDocument.cookieSession.
  2. security ignore m.session (l. 146). Toute opération non publique annonce [{bearer}, {cookie}], alors qu'une route session: true refuse un Authorization. → [{cookie: []}] quand m.session.
  3. Pas de corps de formulaire, pas d'erreur hors enveloppe. MetaApi ne connaît que application/json, et l'enveloppe Error est collée sur tout 4xx (l. 140). La passerelle OAuth d'ATLAS (/api/oauth/token) rend un 400 OAuth {error, error_description} à un corps non x-www-form-urlencoded : le contrat ment, le fuzzing le relève. → un type de corps par route, et des schémas d'erreur propres à une route.
  4. 413 et 503 absents de ERREURS (l. 68-77), alors que lireCorpsBorne et EqsError.unavailable les produisent.

Delta de baseline (cli/src/dispenses.ts, format.ts)

  1. delta() traite null comme une valeur. En CI, les champs « non observés ici » (conformité, otel, checkSeconds…) passent de leur valeur à null, et eqs baseline --diff affiche « 8 changements » à chaque run, sans aucune régression. Le tableau nonObserve est en plus comparé d'un bloc. → une catégorie « non observé ici (baseline : X) », affichée à part et non comptée, et nonObserve comparé comme un ensemble.
  2. eqs baseline --diff refait tout inspect (15 s, et les avertissements deux fois). → --audit <fichier> pour relire l'audit déjà produit.

Mesures CI comparées à des mesures locales

  1. tests.checkSeconds : la baseline vient d'un poste (parallèle, cache chaud, 69 s), la CI mesure en séquentiel à froid (397 s). L'écart est structurel et permanent. → une clé distincte, ou ne pas comparer.

Fidélité de l'audit

  1. hooks.* valent true en CI parce que le script prepare du satellite branche les hooks dans le conteneur. Cela prouve « le dépôt fournit les hooks », pas « les postes les ont ». → le documenter dans SOURCES.

🤖 Generated with Claude Code

Trouvé en lisant les journaux du fuzzing et de l'audit d'ATLAS (run 27, chasse 53). Les contrôles qui passaient sans regarder sont corrigés dans #166. Les points suivants demandent une conception. ## Contrat (`platform-next/src/server/openapi.ts`) 1. **Le nom du cookie de session est écrit en dur** : `better-auth.session_token` (l. 181). ATLAS a renommé ses cookies en `atlas.*`. Une authentification qui suit le contrat, comme le fuzzing derrière la porte (eqs-workflows), enverrait le mauvais cookie. → `OptionsDocument.cookieSession`. 2. **`security` ignore `m.session`** (l. 146). Toute opération non publique annonce `[{bearer}, {cookie}]`, alors qu'une route `session: true` refuse un `Authorization`. → `[{cookie: []}]` quand `m.session`. 3. **Pas de corps de formulaire, pas d'erreur hors enveloppe.** `MetaApi` ne connaît que `application/json`, et l'enveloppe `Error` est collée sur tout 4xx (l. 140). La passerelle OAuth d'ATLAS (`/api/oauth/token`) rend un 400 OAuth `{error, error_description}` à un corps non `x-www-form-urlencoded` : le contrat ment, le fuzzing le relève. → un type de corps par route, et des schémas d'erreur propres à une route. 4. **413 et 503 absents de `ERREURS`** (l. 68-77), alors que `lireCorpsBorne` et `EqsError.unavailable` les produisent. ## Delta de baseline (`cli/src/dispenses.ts`, `format.ts`) 5. `delta()` traite `null` comme une valeur. En CI, les champs « non observés ici » (conformité, otel, `checkSeconds`…) passent de leur valeur à `null`, et `eqs baseline --diff` affiche « 8 changements » à chaque run, sans aucune régression. Le tableau `nonObserve` est en plus comparé d'un bloc. → une catégorie « non observé ici (baseline : X) », affichée à part et non comptée, et `nonObserve` comparé comme un ensemble. 6. `eqs baseline --diff` refait tout `inspect` (15 s, et les avertissements deux fois). → `--audit <fichier>` pour relire l'audit déjà produit. ## Mesures CI comparées à des mesures locales 7. `tests.checkSeconds` : la baseline vient d'un poste (parallèle, cache chaud, 69 s), la CI mesure en séquentiel à froid (397 s). L'écart est structurel et permanent. → une clé distincte, ou ne pas comparer. ## Fidélité de l'audit 8. `hooks.*` valent `true` en CI parce que le script `prepare` du satellite branche les hooks dans le conteneur. Cela prouve « le dépôt fournit les hooks », pas « les postes les ont ». → le documenter dans `SOURCES`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Author
Owner

Un complément au point 4 : 502 manque aussi dans ERREURS (platform-next/dist/server/openapi.js). Or EqsError.upstream le produit depuis n'importe quel handler.

Le fuzzing derrière la porte l'a relevé sur ATLAS (EQS/ATLAS#13, run 77) : POST /api/export/map a rendu 502 UPSTREAM parce que le fond de plan était indisponible, et Schemathesis l'a classé « Undocumented HTTP status code ». ATLAS a 33 endroits qui lèvent 502 ou 503.

Contournement côté ATLAS, en attendant : avecErreursDuSocle (scripts/contrat-openapi.mjs) ajoute à l'export 502 et 503 sur toutes les opérations, et 413 sur celles qui lisent un corps. Une porte, tests/contrat.test.ts, tient cette règle. La fonction n'écrase rien que le socle aurait déjà posé : elle pourra être retirée quand ERREURS portera ces trois statuts.

🤖 Generated with Claude Code

Un complément au point 4 : **502** manque aussi dans `ERREURS` (`platform-next/dist/server/openapi.js`). Or `EqsError.upstream` le produit depuis n'importe quel handler. Le fuzzing derrière la porte l'a relevé sur ATLAS (EQS/ATLAS#13, run 77) : `POST /api/export/map` a rendu `502 UPSTREAM` parce que le fond de plan était indisponible, et Schemathesis l'a classé « Undocumented HTTP status code ». ATLAS a 33 endroits qui lèvent 502 ou 503. **Contournement côté ATLAS, en attendant :** `avecErreursDuSocle` (`scripts/contrat-openapi.mjs`) ajoute à l'export 502 et 503 sur toutes les opérations, et 413 sur celles qui lisent un corps. Une porte, `tests/contrat.test.ts`, tient cette règle. La fonction n'écrase rien que le socle aurait déjà posé : elle pourra être retirée quand `ERREURS` portera ces trois statuts. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
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#167
No description provided.