@mostajs/kind-catalog 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,44 @@
2
2
 
3
3
  **Auteur** : Dr Hamid MADANI <drmdh@msn.com>
4
4
 
5
+ ## 0.2.0 — 2026-09-03
6
+
7
+ ### Ajouté — `enrichir()` : projeter pour CRÉER, enrichir pour EXPLOITER
8
+
9
+ Le passage à qatrax a rendu visible une faute de modèle, et le critère qui la tranche :
10
+
11
+ > **Dans le RÉFÉRENTIEL, une même règle deux fois est une duplication. Dans une APPLICATION, la
12
+ > même règle appliquée à un objet précis est une OCCURRENCE d'exploitation — et il en faut autant
13
+ > qu'il y a d'objets.**
14
+
15
+ `toDevtest` projetait la règle **générique** dans le plan de l'application : ni référentiel, ni
16
+ occurrence — **la règle recopiée**. ATC portait déjà **quatre** occurrences du périmètre (le
17
+ portail, le coaching, l'e-learning, le cumul de rôles) et recevait une cinquième exigence qui ne
18
+ parlait de rien. RestoTrax de même, avec `PIL-10` à `PIL-13`.
19
+
20
+ ```js
21
+ enrichir(plan, { kind, specRefs: ['SPEC-POR-01', 'SPEC-COA-01', 'SPEC-ELE-01', 'SPEC-ROL-02'] })
22
+ ```
23
+
24
+ Les erreurs connues de la fiche descendent dans les exigences **que l'application a déjà**.
25
+ **Aucune exigence, aucun essai n'est ajouté** — ce qui referme *par construction* le défaut que
26
+ qatrax avait signalé : des cas de plan que rien ne peut exécuter, parce qu'ils prétendaient qu'un
27
+ essai portant un autre nom les couvrait.
28
+
29
+ `toDevtest` garde son emploi : une application **neuve**, sans aucune exigence, à qui la fiche
30
+ donne les siennes.
31
+
32
+ **Rejouable** (`T-KC-14`) : le bloc est borné par un marqueur et se remplace au lieu de s'empiler —
33
+ le script d'une application se relance à chaque montée du catalogue.
34
+
35
+ **Refuse plutôt que de faire semblant** (`T-KC-15`) : une exigence introuvable — renommée, le plus
36
+ souvent — est une erreur, pas un avertissement ; et enrichir sans rien désigner est refusé, parce
37
+ que c'est ne rien faire tout en croyant l'avoir fait.
38
+
39
+ `retirerProjection()` reprend ce qu'une projection avait posé, pour les applications qui basculent.
40
+
41
+ 27 essais.
42
+
5
43
  ## 0.1.1 — 2026-09-03
6
44
 
7
45
  ### Ajouté — `bind` : lier une épreuve à l'essai qui la couvre DÉJÀ
@@ -41,6 +41,12 @@
41
41
  "title": "Le corpus livré est valide, sourcé et lisible",
42
42
  "priority": "critical",
43
43
  "status": "verified"
44
+ },
45
+ {
46
+ "ref": "SPEC-KC-08",
47
+ "title": "ENRICHIR les occurrences existantes plutôt que RECOPIER la règle dans le plan de l'application",
48
+ "priority": "critical",
49
+ "status": "verified"
44
50
  }
45
51
  ],
46
52
  "realisations": [
@@ -97,6 +103,15 @@
97
103
  "artifact": "src/",
98
104
  "progress": 100,
99
105
  "status": "done"
106
+ },
107
+ {
108
+ "ref": "REL-KC-08",
109
+ "specRef": "SPEC-KC-08",
110
+ "kind": "feature",
111
+ "title": "enrichir() · retirerProjection()",
112
+ "artifact": "src/enrichir.js",
113
+ "progress": 100,
114
+ "status": "done"
100
115
  }
101
116
  ],
102
117
  "tests": [
@@ -421,6 +436,62 @@
421
436
  "expected": "la liée est `automated` avec son renvoi ; l'autre est `manual` sans renvoi — la déclarer automatisée prétendrait qu'un essai la couvre, et ouvrirait un trou dans la porte qualité de l'application"
422
437
  }
423
438
  ]
439
+ },
440
+ {
441
+ "ref": "T-KC-13",
442
+ "specRef": "SPEC-KC-08",
443
+ "type": "automated",
444
+ "priority": "critical",
445
+ "title": "T-KC-13 — enrichir dépose les erreurs dans les exigences EXISTANTES, sans rien ajouter",
446
+ "autoRef": "test-scripts/unit/catalogue.test.mjs::T-KC-13",
447
+ "steps": [
448
+ {
449
+ "action": "enrichir deux exigences d'un plan",
450
+ "expected": "les descriptions reçoivent les erreurs connues ; aucune exigence ni aucun essai n'est ajouté — c'est ce qui referme le défaut des cas que rien ne peut exécuter"
451
+ }
452
+ ]
453
+ },
454
+ {
455
+ "ref": "T-KC-14",
456
+ "specRef": "SPEC-KC-08",
457
+ "type": "automated",
458
+ "priority": "critical",
459
+ "title": "T-KC-14 — enrichir deux fois ne DOUBLE pas le bloc",
460
+ "autoRef": "test-scripts/unit/catalogue.test.mjs::T-KC-14",
461
+ "steps": [
462
+ {
463
+ "action": "rejouer l'enrichissement",
464
+ "expected": "description inchangée — le script d'une application se rejoue à chaque montée du catalogue"
465
+ }
466
+ ]
467
+ },
468
+ {
469
+ "ref": "T-KC-15",
470
+ "specRef": "SPEC-KC-08",
471
+ "type": "automated",
472
+ "priority": "critical",
473
+ "title": "T-KC-15 — enrichir REFUSE une exigence introuvable, et refuse de ne rien désigner",
474
+ "autoRef": "test-scripts/unit/catalogue.test.mjs::T-KC-15",
475
+ "steps": [
476
+ {
477
+ "action": "exigence renommée, puis liste vide",
478
+ "expected": "refus des deux — une exigence renommée ferait partir l'enrichissement dans le vide, en silence"
479
+ }
480
+ ]
481
+ },
482
+ {
483
+ "ref": "T-KC-16",
484
+ "specRef": "SPEC-KC-08",
485
+ "type": "automated",
486
+ "priority": "critical",
487
+ "title": "T-KC-16 — `retirerProjection` reprend ce qu'une projection avait posé",
488
+ "autoRef": "test-scripts/unit/catalogue.test.mjs::T-KC-16",
489
+ "steps": [
490
+ {
491
+ "action": "projeter puis retirer",
492
+ "expected": "les entrées projetées disparaissent, celles de l'application survivent"
493
+ }
494
+ ]
424
495
  }
425
496
  ]
426
497
  }
package/llms.txt CHANGED
@@ -28,6 +28,10 @@ PIÈGES
28
28
  - Les fiches sont des FICHIERS VERSIONNES (kinds/*.kind.mjs). Ce qui va en base, c'est l'USAGE —
29
29
  et cela appartient a @mostajs/skill-library et au journal d'@mostajs/assistant-pilote.
30
30
  - AUCUN FORMAT NOUVEAU : la projection produit du mostajs-devtest/1, valide par le parseur officiel.
31
+ - PROJETER POUR CREER, ENRICHIR POUR EXPLOITER. Dans le REFERENTIEL, une regle deux fois = duplication ;
32
+ dans une APPLICATION, la regle appliquee a un objet = OCCURRENCE, et il en faut autant qu'il y a d'objets.
33
+ toDevtest = app NEUVE (elle recoit ses exigences) · enrichir = app EXISTANTE (ses occurrences recoivent
34
+ les erreurs connues). enrichir n'AJOUTE ni exigence ni essai — sinon qatrax porte des cas inexecutables.
31
35
  - loadCatalogue() fait un import() : charger un corpus, c'est EXECUTER du code. Une fiche se revoit
32
36
  comme du code, jamais comme un document (docs/15-REVUE-SECURITE).
33
37
  - validateKind() applique les memes defauts que defineKind : on peut lui passer un objet BRUT.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mostajs/kind-catalog",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Catalogue de KINDS — fiches d'exigence réutilisables, projetables en plan mostajs-devtest/1 lisible par qatrax. N'exécute rien, ne stocke rien.",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-or-later",
@@ -0,0 +1,91 @@
1
+ /**
2
+ * ENRICHIR — faire descendre les erreurs connues d'une fiche dans les exigences QUE
3
+ * L'APPLICATION A DÉJÀ.
4
+ *
5
+ * ── PROJETER POUR CRÉER, ENRICHIR POUR EXPLOITER ───────────────────────────
6
+ * `toDevtest` sert à une application NEUVE : elle n'a aucune exigence, la fiche lui donne les
7
+ * siennes. `enrichir` sert à une application qui EN A DÉJÀ — et c'est le cas courant, puisqu'une
8
+ * fiche naît précisément de ce que des applications ont éprouvé.
9
+ *
10
+ * ⚠️ LE CRITÈRE QUI SÉPARE LES DEUX (décision du 03/09/2026, après un passage à qatrax qui l'a
11
+ * rendu visible) :
12
+ *
13
+ * · dans le RÉFÉRENTIEL, une même règle deux fois est une DUPLICATION ;
14
+ * · dans une APPLICATION, la même règle appliquée à un objet précis est une OCCURRENCE
15
+ * d'exploitation, et il en faut autant qu'il y a d'objets.
16
+ *
17
+ * D'où la faute que cette fonction répare : projeter la règle GÉNÉRIQUE dans le plan d'une
18
+ * application ajoutait une exigence qui n'était appliquée à rien. Ni référentiel, ni occurrence :
19
+ * la règle recopiée. ATC portait déjà QUATRE occurrences du périmètre — le portail, le coaching,
20
+ * l'e-learning, le cumul de rôles — et recevait une cinquième exigence qui ne parlait de rien.
21
+ *
22
+ * ⚠️ ELLE N'AJOUTE NI EXIGENCE NI ESSAI. C'est ce qui referme, par construction, le défaut que
23
+ * qatrax avait signalé : des cas de plan que rien ne peut exécuter, parce qu'ils prétendaient
24
+ * qu'un essai portant un autre nom les couvrait.
25
+ *
26
+ * Author: Dr Hamid MADANI <drmdh@msn.com> · AGPL-3.0-or-later
27
+ */
28
+ const propre = (v) => String(v ?? '').trim();
29
+
30
+ /** La borne du bloc ajouté — elle rend l'enrichissement REJOUABLE sans empiler. */
31
+ export const marqueur = (ref) => `⟦${ref}⟧`;
32
+
33
+ /** Le bloc que la fiche dépose dans une exigence de l'application. */
34
+ export function blocDeFiche(k) {
35
+ return [
36
+ marqueur(k.ref),
37
+ `Fiche ${k.ref} v${k.version} (${k.verdict}) — ce que d'autres projets ont payé :`,
38
+ ...k.erreurs.map((e) => `⚠ ${e.titre} — ${e.consequence}`),
39
+ ].join('\n');
40
+ }
41
+
42
+ /**
43
+ * Enrichit des exigences EXISTANTES avec les erreurs connues d'une fiche.
44
+ *
45
+ * @param {object} plan plan `mostajs-devtest/1` de l'application — modifié en place
46
+ * @param {object} o
47
+ * @param {object} o.kind la fiche (ou son instance affinée)
48
+ * @param {string[]} o.specRefs les exigences de l'application qui sont des OCCURRENCES de la règle
49
+ * @returns {{ enrichies: string[], bloc: string }}
50
+ */
51
+ export function enrichir(plan, { kind, specRefs = [] } = {}) {
52
+ if (!plan?.specs) throw new Error('enrichir: plan `mostajs-devtest/1` requis');
53
+ if (!kind?.ref) throw new Error('enrichir: fiche requise');
54
+ if (!specRefs.length) {
55
+ // ⚠️ ENRICHIR SANS DIRE QUOI, C'EST NE RIEN FAIRE — et croire l'avoir fait. On refuse plutôt
56
+ // que de rendre un rapport vide qui passerait pour un succès.
57
+ throw new Error(`enrichir(${kind.ref}) : aucune exigence désignée — une fiche s’applique à des OCCURRENCES, nommez-les`);
58
+ }
59
+
60
+ const bloc = blocDeFiche(kind);
61
+ const enrichies = [];
62
+ for (const ref of specRefs) {
63
+ const s = plan.specs.find((x) => x.ref === propre(ref));
64
+ // ⚠️ UNE EXIGENCE INTROUVABLE EST UNE ERREUR, pas un avertissement : le plus probable est
65
+ // qu'elle a été renommée, et l'enrichissement partirait alors dans le vide en silence.
66
+ if (!s) throw new Error(`enrichir(${kind.ref}) : exigence introuvable — ${ref}`);
67
+ const tete = String(s.description ?? '').split(marqueur(kind.ref))[0].trimEnd();
68
+ s.description = tete ? `${tete}\n\n${bloc}` : bloc;
69
+ enrichies.push(s.ref);
70
+ }
71
+ return { enrichies, bloc };
72
+ }
73
+
74
+ /**
75
+ * Retire d'un plan ce qu'une PROJECTION y avait posé — exigences, réalisations et essais.
76
+ * Utile une fois : quand une application passe de `toDevtest` à `enrichir`.
77
+ */
78
+ export function retirerProjection(plan, { kind, prefix } = {}) {
79
+ const corps = propre(kind?.ref ?? kind).replace(/^KIND-/, '');
80
+ const p = propre(prefix).toUpperCase();
81
+ const cible = { specs: `SPEC-${p}-${corps}`, realisations: `REL-${p}-${corps}`, tests: `T-${p}-${corps}-` };
82
+ const retires = [];
83
+ for (const [cle, debut] of Object.entries(cible)) {
84
+ const reste = [];
85
+ for (const l of plan[cle] ?? []) {
86
+ if (l.ref === debut || String(l.ref).startsWith(debut)) retires.push(l.ref); else reste.push(l);
87
+ }
88
+ plan[cle] = reste;
89
+ }
90
+ return retires;
91
+ }
package/src/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { defineKind, validateKind, VERDICTS, PROVENANCES, DOMAINES } from './kind.js';
2
2
  export { toDevtest, PLAN_VERSION } from './projection.js';
3
+ export { enrichir, retirerProjection, blocDeFiche, marqueur } from './enrichir.js';
3
4
  export { instantiate, diffInstance, emplois, AFFINABLES } from './instance.js';
4
5
  export { loadCatalogue, findKinds, auditCatalogue, statsCatalogue } from './catalogue.js';