@mostajs/recette
v0.2.1
Published
Validation & recette applicative : trame `mostajs-devtest/1` reçue signée du certificateur, points enrichis POUR LE CLIENT (l'import n'écrase jamais l'enrichissement), feuillets composés à l'image du manifeste PDF (ok/ko/er), anomalies déclarées puis qual
Maintainers
Readme
@mostajs/recette — validation & recette applicative
Auteur : Dr Hamid MADANI [email protected] · AGPL-3.0-or-later Niveau : N3 métier · Forme : moteur · Dépend de : aucun autre N3
Le moteur de la recette : une trame reçue du certificateur, des points enrichis pour le client,
des feuillets composés, des relevés ok/ko/er, des anomalies déclarées puis qualifiées, un
dossier figé et exporté signé — puis un certificat reçu, vérifié, et un feu d'exploitation qui
en dérive.
Il fait tourner ValiTrax (valitrax.mostajs.dev), par lequel un éditeur délègue la recette à
son client ou à son équipe.
La chaîne, et son transport
DEV → QaTrax ═══ trame signée ═══════════════▶ ValiTrax ───▶ le CLIENT
AUTOMATIQUE (deux de nos serveurs) │ lit, coche
QaTrax ◀── dossier figé, signé (et scellé) ────┘
│ À LA MAIN — le document passe par le client
│ vérifie · valide le cycle · scelle le PV
└──────── certificat signé + le feu ────────▶ ValiTrax → l'expose au client → PRODLe transport est ASYMÉTRIQUE, et c'est voulu.
L'aller est automatique : la trame relie deux de vos serveurs, rien n'y justifie une main.
trame.synchroniser() la tire par un port injecté — le moteur ne connaît ni URL ni jeton.
Le retour est humain, parce que le document passe par le client : c'est lui qui valide, et c'est lui qui rend. Ce n'est pas un pis-aller — c'est ce qui permet à un client sans accès vers vos serveurs de rendre sa recette.
La signature vaut dans les deux sens, y compris sur le canal automatique : un canal direct dit d'où vient la connexion, pas ce que le document contient. Une mauvaise URL injecterait une trame étrangère sans bruit, et le client éprouverait autre chose que le spécifié — sans pouvoir s'en apercevoir, faute de référentiel.
QaTrax FAIT le PV. ValiTrax l'EXPOSE. Le client ne va jamais sur QaTrax : c'est un outil de développement, et l'écarter est la raison d'être de ValiTrax.
Ce qu'il ne fait pas
| il ne fait pas | qui le fait |
|---|---|
| tests, exécutions, bugs, version candidate | @mostajs/qa-engine — référencés, jamais recopiés |
| produire les formulaires du client | ce module — QaTrax n'envoie que la trame |
| émettre le certificat | le certificateur (QaTrax) — ce module le reçoit et le vérifie |
| implémenter la cryptographie | @mostajs/crypto-box — Ed25519, enveloppe X25519 |
| sceller un PV collégial · le rendre vérifiable par QR | @mostajs/deliberation · @mostajs/certificates (côté certificateur) |
| fils, mentions · convocations | @mostajs/collab · @mostajs/notifications |
| engendrer les PDF des feuillets | l'outillage de l'application |
| lire une feuille photographiée | @mostajs/ocr |
Le point de recette — deux moitiés, une frontière
côté TRAME (vient de QaTrax) côté ENRICHISSEMENT (appartient à ValiTrax)
ref · specRef · titreTrame libelle · attendu · role · ordre · langue · retenu
priorite · etapesTrame ─────────────────────────────────────────────────
réécrit à chaque import L'IMPORT N'Y TOUCHE JAMAIS« Vérifier que
POST /dossiersrefuse un livrable non accepté » est un titre de trame. « Essayez de programmer une soutenance sur un dossier dont un livrable manque — le refus doit dire lequel » est un libellé de recette.
Même exigence, deux lecteurs, deux textes. Une trame se réimporte à chaque version candidate ; si l'import régénérait les points, chaque réimport effacerait la formulation écrite pour le client, les rôles et l'ordre — et l'on ne s'en apercevrait qu'en distribuant les feuillets.
La sélection se fait dans ValiTrax, pas chez QaTrax : la trame arrive entière, points.retenir()
en garde une partie. C'est le responsable de recette qui sait ce que SON client doit éprouver.
Le client n'est pas une machine : il lit, il coche
feuillets.composer() rend exactement la structure du manifeste des feuillets PDF :
{ genre: 'action', ref: 'T-APP-9', libelle: 'Programmez la soutenance',
attendu: 'le refus nomme le livrable', specRef: 'SPEC-APP-09',
enrichi: true, options: ['ok', 'ko', 'er'] }Papier, écran et moteur parlent une seule langue. Un troisième format, et l'on retomberait dans la divination : quel rectangle porte quelle réponse ?
enrichi dit si le client lira du français de métier ou un titre de cas de test. Un point non
enrichi reste lisible — mais cela se voit.
Trois valeurs, plus l'absence
| | ce que ça dit | ce qu'on corrige |
|---|---|---|
| ok | conforme | rien |
| ko | le logiciel marche, mais autrement que le plan l'annonce | le document |
| er | exception, panne | le code |
| rien | non joué — l'étape précédente bloquait | l'ordonnancement de la séance |
ko et er n'ont ni le même destinataire ni la même urgence.
Usage
import { createRecette, createMemoryRepositories } from '@mostajs/recette';
import { creerSceau } from '@mostajs/recette/sceau'; // chemin à part : lui seul importe crypto-box
const recette = createRecette({
repositories,
ports: {
trameSource: { lire: ({ projet }) => fetch(`${QATRAX}/trame?p=${projet}`).then((r) => r.json()) },
sceau: creerSceau({
signature: { privee: process.env.VALITRAX_CLE_PRIVEE, nom: 'valitrax' }, // NOTRE identité
destinataire: { publique: process.env.QATRAX_CLE_RECEPTION }, // sceller pour eux
certificateur: { publique: process.env.QATRAX_CLE_SIGNATURE }, // vérifier leur PV
}),
},
});
const c = await recette.campagnes.ouvrir({ releaseRef: 'qatrax:release:42', instanceUrl: 'https://banc…' });
await recette.trame.synchroniser(c.id, { projet: 'labtrax' }); // tirée de QaTrax, vérifiée, idempotente
await recette.points.enrichir(pointId, { libelle: '…', attendu: '…', role: 'S' });
await recette.points.retenir(c.id, ['T-APP-9', 'T-APP-13']);
await recette.campagnes.avancer(c.id, 'verification');
const { feuillet, cases } = await recette.feuillets.composer({ campagneId: c.id, role: 'S' });
// … consigner · rendre · figer · exporter · recevoir le certificat · autoriser l'exploitationSigner et sceller ne sont pas la même chose
| | avec quelle clé | ce que ça prouve | |---|---|---| | signer | notre privée (Ed25519) | l'origine — un document signé se lit par tous | | sceller | la publique du destinataire (X25519) | le pli fermé — lui seul ouvre, rien n'est authentifié |
L'ordre est signer PUIS sceller. Sceller d'abord signerait un chiffré : on prouverait avoir transmis une boîte, pas ce qu'elle contient.
Les verbes du sceau n'existent que si leur clé existe. Une clé manquante se voit donc au démarrage, et non à la fin de la recette quand tout le monde attend le document.
Les gardes — c'est par elles qu'il faut juger ce module
- Une recette ne se joue pas sur la production : l'URL est refusée.
- Le parcours ne saute pas de cran —
candidate → verification → recette → validation → figee → certifiee → exploitation. - La trame est vérifiée : enveloppe
mostajs-recette-trame/1, planmostajs-devtest/1, signature valide — même sur le canal automatique, sinon refus. - L'import n'écrase jamais l'enrichissement, et dit combien il en a préservé.
- On n'enrichit pas par-dessus la trame :
titreTrame,specRefet consorts sont refusés. - On ne consigne que sur un feuillet REMIS, et un
erporte son heure. - Qualifier n'efface pas la gravité annoncée par le client — le désaccord reste lisible.
- Écarter une anomalie exige un motif.
- Le figement refuse et NOMME ce qui manque : feuillets non rendus, anomalies non qualifiées, bloquantes ni vérifiées ni écartées.
- Un export non signé est refusé : il ne prouverait rien, et c'est tout ce qu'on lui demande.
- Le certificat doit citer l'EMPREINTE du dossier, et sa signature est vérifiée.
- Le feu dérive du certificat : pas de certificat, verdict
refuse, ou certificat sans le feu — l'exploitation reste fermée.
L'empreinte décide de tout
Le dossier figé porte un SHA-256 de son contenu, et le certificat reçu doit la citer. Sans elle, un certificat porterait sur « la recette » — c'est-à-dire sur rien de vérifiable. Avec elle, il porte sur ce dossier-là, et le client peut le prouver seul.
Essais
npm test # 13 essais — ils éprouvent ce que le moteur REFUSEUn moteur de recette qui accepte tout ne sert à rien : c'est le document Word qu'il remplace.
