Cause racine du dernier test Mocha en echec (getAuditBatch flaguait "Faire mijoter a feu doux" comme peu fiable malgre une ancre NER claire) : avec seulement 30 iterations/dropout 0.2, le textcat retournait le bon intent (argmax correct) mais avec une confiance tres basse et compressee (0.2-0.7 sur l'ensemble du corpus reel, y compris des cas evidents) — un vrai probleme de qualite d'entrainement, pas seulement de seuil. 150 iterations / lot de 16 / dropout 0.1 (mesure localement contre le vrai corpus, sans Postgres) : melt ~0.95, preheat ~0.90, jusqu'a ~0.51 pour le cas le plus faible observe (bake), bruit hors-vocabulaire toujours ~0.05. ~110s d'entrainement par locale (~220s pour fr+en au warm-up) — compromis assume et documente (README du service, commentaires du code), contrairement a l'entrainement quasi instantane de node-nlp. Root hook Mocha (mocha-root-hooks.ts) et sa doc mis a jour avec un timeout de 600s pour couvrir cette duree avec marge. Verifie : 27/27 pytest, lint + build complets du monorepo. Suite Mocha a confirmer sur ce commit via CI (source du diagnostic qui a mene a ce fix). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
46 lines
2.7 KiB
TypeScript
46 lines
2.7 KiB
TypeScript
import { techStepClassifier } from "../src/lib/recipe-matching/tech-step-matcher.js";
|
|
import { resetDatabase } from "./reset-db.js";
|
|
|
|
/**
|
|
* Mocha root hook plugin (see `.mocharc.json`'s `require`) — runs once
|
|
* before every test file's own suites, regardless of load order.
|
|
*
|
|
* Warms up `techStepClassifier` here, with its own generous timeout,
|
|
* instead of leaving it to happen lazily on whichever test file Mocha
|
|
* happens to load first. In production this one-time cost (a `POST
|
|
* /v1/train` round-trip per locale to `services/tech-step-intent-service`,
|
|
* training a real `textcat` on the full `TECH_STEP_TRAINING_DATA` corpus)
|
|
* is paid by `server.ts`'s own `techStepClassifier.warmUp()` before the
|
|
* server ever accepts traffic — but this test suite builds its `app`
|
|
* directly via `createApp()` (see e.g. `tech-step-worker.routes.test.ts`),
|
|
* never running `server.ts` at all. Without this hook, that cost instead
|
|
* landed inside whichever test's own call happened to trigger
|
|
* `_ensureTrained()` first — found the hard way in CI, where training the
|
|
* full corpus took longer than a single test's default 10s timeout
|
|
* (`.mocharc.json`) and failed an otherwise-unrelated test purely because
|
|
* Mocha loaded its file first alphabetically.
|
|
*
|
|
* `resetDatabase()` runs first, deliberately: `_train()`
|
|
* (`tech-step-matcher.ts`) resolves `TechStep.key -> id` from the database
|
|
* alongside training, and a freshly-migrated (never-seeded) test database
|
|
* has no `TechStep` rows yet — every per-test `beforeEach` in this suite
|
|
* already calls `resetDatabase()` again before its own test, which is a
|
|
* no-op duplication of effort but not a correctness problem: `TRUNCATE ...
|
|
* RESTART IDENTITY` plus deterministic re-seeding (`seedReferenceData`)
|
|
* assigns the exact same ids every time, so the `uid -> id` map memoized
|
|
* here from this first reset stays valid for every reset after it.
|
|
*/
|
|
export const mochaHooks = {
|
|
// biome-ignore lint/suspicious/noExplicitAny: Mocha's root hook `this` (a Context with `.timeout()`) isn't typed without @types/mocha (not a dependency here) — same untyped-`this` shape already used in tech-step-worker.routes.test.ts.
|
|
async beforeAll(this: any): Promise<void> {
|
|
// Generous on purpose: training both locales' `textcat` on the full
|
|
// corpus takes on the order of a couple of minutes combined (see
|
|
// `_TRAINING_ITERATIONS` in `services/tech-step-intent-service`'s
|
|
// `locale_pipeline.py`) — comfortably under 10 minutes even on a
|
|
// slower/contended CI runner, but nowhere near Mocha's normal 10s
|
|
// per-test default (`.mocharc.json`).
|
|
this.timeout(600000);
|
|
await resetDatabase();
|
|
await techStepClassifier.warmUp();
|
|
},
|
|
};
|