dev #7

Merged
nicolas-fryder merged 6 commits from dev into main 2026-09-16 21:21:17 +00:00
No description provided.
Tout le câblage qui manquait à `apps/api`, et deux ajouts à l'application
elle-même.

Le contexte `testing` reçoit `root`, `conteneurs` (privé du projet de cette
suite) et la durée du dernier `eqs check` lue dans la baseline :
`check-budget` et `base-detruite` cessent d'être muets.

La télémétrie reçoit un vrai collecteur OTLP et un serveur instrumenté — le
harnais `nest` du socle n'en fournit aucun. `serveurInstrumente` est ajouté à
`processus.ts` : `boot` attendait que le processus SORTE, puisqu'il éprouve un
refus de démarrage, et il fallait l'inverse.

L'application gagne une cible « boucle » et une route `/api/demo/sortant`, sans
intérêt métier et assumé : c'est le seul appel sortant qu'on puisse faire
partout sans dépendre d'un tiers, et `telemetry.traceparent-propage` doit voir
un `traceparent` arriver quelque part. L'adresse vient de `adresseBoucle()` et
non de `process.env`, que `config.lecture-hors-module` refuse à un contrôleur.

`LOG_LEVEL: 'info'` pour le serveur instrumenté : le reste de la suite tourne en
`error`, et `log.info` était donc filtré. `telemetry.log-correle` accusait
« aucun log ne porte le trace_id » sur un service qui journalisait bien — zéro
enregistrement reçu, alors que neuf spans arrivaient.

Résultat mesuré : 15 cas verts sur 17, et 12 règles muettes au lieu de 29 —
toutes du groupe `auth`, toutes retenues par le seul `auth.403-audience`.

`bundleDir: null` ne comptera qu'une fois le socle publié. Il passe le typage
aujourd'hui parce que `options` est un `Record<string, unknown>` : une clé mal
typée y est silencieuse, ce qui est une faiblesse en soi.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`auth.403-audience` était le dernier contrôle non exécutable, et il retenait les
douze règles du groupe `auth` — un contrôle empêché n'en apporte aucune.

Il n'était jouable nulle part : `principalDepuisJetonEntra` vérifie la SIGNATURE
avant l'audience, ce qui est le bon ordre, mais veut dire qu'un jeton bricolé
échoue en 401 et n'atteint jamais le 403 que le contrôle cherche. Il faut de
vraies clés. La suite en fabrique une paire, signe un jeton valide en tout point
SAUF l'audience, et fournit le jeu de clés publiques à l'application — le socle
accepte désormais ce point d'injection.

`jose` passe en dépendance de DÉVELOPPEMENT et n'ajoute rien au déploiement :
il est déjà tiré en production par `@eqs/auth` et par `better-auth`. Vérifié
plutôt que supposé — une seule copie dans l'arbre après ajout, et l'étage
d'exécution de l'image ne copie que la sortie tracée par Next.

Ce champ `entra` n'existe que pour un harnais. En production il est absent, et
c'est son absence qui garantit que les jetons sont vérifiés contre Microsoft.

Il ne prendra effet qu'une fois le socle publié. Il passe le typage aujourd'hui
parce qu'une clause conditionnelle (`...(x ? { entra } : {})`) échappe à la
vérification — même faiblesse que le `Record<string, unknown>` d'`options`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`auth.403-audience` jouait déjà dans `nest` ; il manquait au front. `creerApi`
est appelé à la portée du module dans `src/lib/api.ts`, donc aucun harnais ne
peut lui injecter un JWKS sans mettre une couture de test dans la source de
production. Le socle accepte désormais un `fetchAudience` : la suite monte une
instance JETABLE avec les clés qu'elle contrôle et ne la donne qu'à ce contrôle.
Tout le reste continue de frapper l'application réelle.

DEUX DÉFAUTS TROUVÉS EN CHEMIN, et le premier est le plus gênant :

Le vert de la suite `api` dépendait du `.env` du poste. `reglesDeBase` exige les
trois `MS_*` ensemble et c'est bloquant ; la suite n'en posait que deux, et
passait uniquement parce que `source` inclut `process.env` et que la machine
porte les quatre. Sur un poste propre ou en CI, elle aurait rougi sur une
configuration incohérente — pour une raison sans rapport avec ce qu'elle
éprouve. Les quatre sont maintenant posées par la suite. Aucune n'est un
secret : le locataire n'existe pas.

Une règle ne se déclenche QUE quand Entra est configuré : `PUBLIC_URL` en
`http://` hors localhost, qu'Entra refuserait comme URI de retour. Elle ne
s'était donc jamais vue ici.

Le relais de `fetchAudience` est stable et lit tard : les options de
`runConformance` sont lues au chargement du module, et passer la fonction
directement transmettait `undefined` — le contrôle retombait sur le `fetch`
ordinaire et lisait un 401. Même piège que `contexteTelemetry`, même remède.

`jose` en dépendance de développement du front, pour la même raison qu'à l'api :
déjà tiré en production, une seule copie dans l'arbre.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Les deux profils sont entièrement joués : 32 sur 32 pour `next-fullstack`, 17
sur 17 pour `nest`. Le profil du gabarit, que trente satellites clonent,
n'était éprouvé par aucune application réelle ce matin.

Consigné aussi : quatre contrôles accusaient des services corrects, et un vert
dépendait du `.env` du poste.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`eqs check` déclarait une tâche `knip` depuis le début et `@eqs/tooling` publie
sa base, mais knip n'était installé dans AUCUN satellite. La tâche se retirait
« faute d'outil », en le disant, et la porte annonçait une tâche de moins
qu'elle n'en jouait — le détecteur de code mort était éteint dans toute la
flotte.

Deux lignes de configuration, et c'est délibéré : `knipSatellite()` déduit les
points d'entrée de ce qu'il y a sur le disque. Devinés, ils font passer du code
vivant pour mort.

Trois trouvailles, toutes des faux positifs de FORME, chacune corrigée à son
niveau :

- deux fixtures lancées par `spawn`, donc jamais importées. Corrigé dans le
  socle (`test/**/*.mjs` en entrée, à côté du `.mts` qui y était déjà) et
  déclaré ici en attendant sa publication ;
- `ssh-keygen`, un binaire du SYSTÈME dont le bac à sable se sert. Déclaré ici
  et pas dans la base de la flotte : aucun autre satellite n'a de bac à sable,
  et une exception poussée dans une base commune la transforme en fourre-tout.

Porte complète : neuf tâches, toutes vertes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Socle 0.11.2, et les déclarations provisoires tombent
Some checks failed
ci.yml / Socle 0.11.2, et les déclarations provisoires tombent (pull_request) Failing after 0s
34479cbfba
Les deux suites restent entières contre le socle publié : 32 sur 32 pour
`next-fullstack`, 17 sur 17 pour `nest`, zéro règle muette.

`knip.ts` perd les trois entrées que j'avais datées : `@eqs/tooling` 0.11.2
déclare lui-même `test/**/*.mjs` en point d'entrée d'un satellite. Seul reste
`ssh-keygen`, qui est propre à ce dépôt — aucun autre satellite n'a de bac à
sable Coolify.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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-demo!7
No description provided.