@mostajs/kind-catalog 0.1.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 +136 -0
- package/README.md +103 -0
- package/docs/00-ETAPE-INAUGURALE-KIND-CATALOG.md +105 -0
- package/docs/03bis-PROMPT-IMAGE-OBJECTIF-KIND-CATALOG.md +99 -0
- package/docs/09bis-MATRICE-SOURCING-KIND-CATALOG.md +176 -0
- package/docs/10-PRESENTATION-COMMERCIALE-KIND-CATALOG.md +140 -0
- package/docs/11-SLIDES-COMMERCIAL-KIND-CATALOG.md +154 -0
- package/docs/12-DOC-TECHNIQUE-KIND-CATALOG.md +164 -0
- package/docs/13-SLIDES-DEV-KIND-CATALOG.md +162 -0
- package/docs/14-PROMPT-IMAGE-KIND-CATALOG.md +88 -0
- package/docs/15-REVUE-SECURITE-KIND-CATALOG.md +98 -0
- package/docs/16-DPIA-CONFORMITE-KIND-CATALOG.md +100 -0
- package/docs/ARTICLE-SEO-KIND-CATALOG.md +96 -0
- package/docs/AUDIT-EXISTANT-KIND-CATALOG.md +127 -0
- package/docs/DEVTEST-PLAN.kind-catalog.json +412 -0
- package/docs/ETUDE-ETAT-ART-KIND-CATALOG-02092026.md +207 -0
- package/docs/PLAN-DEV-KIND-CATALOG.md +186 -0
- package/docs/PLAN-PUBLICATION-KIND-CATALOG.md +80 -0
- package/docs/PLAN-SUIVI-MONITORING.md +66 -0
- package/docs/PLAN-TESTS.md +79 -0
- package/docs/SEO-KEYWORDS-KIND-CATALOG.md +46 -0
- package/docs/articles/01-ARTICLE-KIND-CATALOG.md +229 -0
- package/kinds/acces.kind.mjs +48 -0
- package/kinds/apprentissage.kind.mjs +25 -0
- package/kinds/chiffres.kind.mjs +80 -0
- package/kinds/decision.kind.mjs +88 -0
- package/kinds/donnees.kind.mjs +108 -0
- package/kinds/ecran-service.kind.mjs +71 -0
- package/kinds/integration.kind.mjs +83 -0
- package/kinds/metier-optimisation.kind.mjs +210 -0
- package/kinds/traces.kind.mjs +39 -0
- package/llms.txt +34 -0
- package/package.json +46 -0
- package/src/catalogue.js +98 -0
- package/src/index.js +4 -0
- package/src/instance.js +85 -0
- package/src/kind.js +152 -0
- package/src/projection.js +76 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Le catalogue qu'il manquait aux exigences
|
|
2
|
+
|
|
3
|
+
*Ce que vingt ans de catalogues d'erreurs nous apprennent, et pourquoi personne ne l'avait appliqué
|
|
4
|
+
aux exigences.*
|
|
5
|
+
|
|
6
|
+
**Auteur** : Dr Hamid MADANI <drmdh@msn.com> · **Date** : 2026-09-02
|
|
7
|
+
**Livrable #17** (DEVRULES §9) · module `@mostajs/kind-catalog` 0.1.0
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Résumé
|
|
12
|
+
|
|
13
|
+
En une semaine, sur deux applications en production, nous avons trouvé cinq défauts. Aucun ne
|
|
14
|
+
plantait ; tous étaient silencieux ; **aucun n'était nouveau**. Chacun avait une littérature, un
|
|
15
|
+
nom, parfois une norme — et rien ne les attendait dans le projet suivant.
|
|
16
|
+
|
|
17
|
+
La sécurité applicative a résolu ce problème il y a vingt ans avec CWE : un catalogue d'erreurs
|
|
18
|
+
connues, chacune portant **sa conséquence**, nourri par des faits observés, et **branché aux
|
|
19
|
+
outils**. L'ingénierie des exigences, elle, n'a jamais eu son CWE — le meilleur catalogue de
|
|
20
|
+
patrons d'exigences existant, celui de Withall (2007), n'est branché à rien et est resté un livre.
|
|
21
|
+
|
|
22
|
+
`@mostajs/kind-catalog` occupe cet écart : des fiches d'exigence réutilisables portant l'énoncé, les
|
|
23
|
+
critères de succès, les **erreurs connues avec leur conséquence** et les épreuves — et qui **se
|
|
24
|
+
projettent dans le plan de test du projet**, au format que l'outil de suivi lit déjà. Le module
|
|
25
|
+
n'exécute rien et ne stocke rien. Livré avec **12 fiches, 39 erreurs cataloguées, 10 domaines,
|
|
26
|
+
50 % d'éprouvé**.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 1 · État de l'art des outils à implémentation commune
|
|
31
|
+
|
|
32
|
+
Cinq familles d'outils cataloguent quelque chose de proche. Aucune ne catalogue l'ensemble.
|
|
33
|
+
|
|
34
|
+
**Les patrons d'exigences.** *Software Requirement Patterns* (Withall, 2007) est l'ancêtre direct :
|
|
35
|
+
un catalogue de gabarits réutilisables, avec exemples et « considérations » — c'est-à-dire les
|
|
36
|
+
pièges. Il prouve qu'une exigence se catalogue. **Il n'est branché à aucun outil**, et c'est sa
|
|
37
|
+
limite décisive.
|
|
38
|
+
|
|
39
|
+
**La syntaxe contrainte.** EARS (Mavin *et al.*, 2009) impose cinq formes de phrase et réduit
|
|
40
|
+
l'ambiguïté. Elle contraint **l'énoncé** — ni l'épreuve, ni le mode de défaillance, ni le réemploi.
|
|
41
|
+
|
|
42
|
+
**Les normes.** ISO/IEC/IEEE 29148 fixe les attributs d'une exigence, dont la **vérifiabilité** :
|
|
43
|
+
une exigence non vérifiable n'en est pas une. Elle normalise la forme d'un **document**, pas un
|
|
44
|
+
corpus partagé.
|
|
45
|
+
|
|
46
|
+
**Les catalogues d'erreurs.** CWE, CAPEC, ATT&CK, OWASP Top 10. C'est le modèle le plus proche de
|
|
47
|
+
ce que nous construisons, et il enseigne trois choses : chaque entrée porte sa **conséquence** ; le
|
|
48
|
+
catalogue est nourri par des **faits observés** ; et **la brièveté fait la lecture** — CWE compte
|
|
49
|
+
plus de mille entrées, et ce que les équipes lisent est le Top 10.
|
|
50
|
+
|
|
51
|
+
**Les décisions d'architecture.** Les ADR (Nygard, 2011) démontrent que le bon support d'un
|
|
52
|
+
document qui se **relit** est un **fichier versionné**. C'est l'argument qui a tranché notre
|
|
53
|
+
question de stockage.
|
|
54
|
+
|
|
55
|
+
**Le raisonnement à partir de cas.** Aamodt & Plaza (1994) : retrouver, réutiliser, **réviser**,
|
|
56
|
+
retenir. La révision est une **étape du cycle**, pas un accident — c'est exactement le geste
|
|
57
|
+
« réutiliser ou affiner ».
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 2 · Description des algorithmes
|
|
62
|
+
|
|
63
|
+
Le module **ne contient aucun algorithme de calcul**, et c'est délibéré. Les moteurs sont ceux de
|
|
64
|
+
`@mostajs/ro-pla` : 23 dialectes répartis en 12 familles — affectation (hongrois, appariement
|
|
65
|
+
stable, couplage général), programmation linéaire et en nombres entiers (simplexe, séparation et
|
|
66
|
+
évaluation, sac à dos), flots (coût minimal, plus court chemin, flot maximal), ordonnancement
|
|
67
|
+
(chemin critique, rangement, ordonnancement de liste), files d'attente, chaînes de Markov,
|
|
68
|
+
décision markovienne, satisfaction de contraintes, métaheuristiques, simulation, multiobjectif.
|
|
69
|
+
|
|
70
|
+
Ce que le module apporte est d'un autre ordre : **quatre traitements**, tous déterministes et purs.
|
|
71
|
+
|
|
72
|
+
**La validation d'une fiche.** Contrôle de forme, rendu comme **liste complète** de reproches et non
|
|
73
|
+
au premier échec : corriger un manque pour en découvrir un autre fait abandonner.
|
|
74
|
+
|
|
75
|
+
**La projection.** Transformation d'une fiche en un plan `mostajs-devtest/1` : une exigence, une
|
|
76
|
+
réalisation, un essai par épreuve déclarée. Le préfixe d'application **isole** deux projets
|
|
77
|
+
reprenant la même fiche. Une fiche seulement `propose` se projette en statut `draft` — jamais
|
|
78
|
+
`verified`.
|
|
79
|
+
|
|
80
|
+
**L'instanciation.** Application d'un ensemble d'affinages, chacun **exigeant son motif**, suivie
|
|
81
|
+
d'une revalidation : on n'affine pas jusqu'à vider l'exigence de sa substance.
|
|
82
|
+
|
|
83
|
+
**L'agrégation.** Index inverse des emplois, et statistiques du corpus — dont le **taux éprouvé**,
|
|
84
|
+
le seul chiffre qui engage.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 3 · Motif de sélection
|
|
89
|
+
|
|
90
|
+
**Pourquoi aucun format nouveau.** Un second format aurait demandé un second validateur, un second
|
|
91
|
+
import, un second écran. Et le jour où les deux divergent, **c'est le catalogue qui aurait raison
|
|
92
|
+
contre les faits**. La projection produit donc du `mostajs-devtest/1`, et l'essai la soumet au
|
|
93
|
+
**parseur officiel** de `@mostajs/qa-engine` — une vérification maison ne prouverait que notre
|
|
94
|
+
accord avec nous-mêmes.
|
|
95
|
+
|
|
96
|
+
**Pourquoi des fichiers plutôt qu'une base.** Une fiche est un document éditorial : elle se lit, se
|
|
97
|
+
discute, se relit six mois plus tard. Son historique est celui d'un fichier — c'est le modèle ADR.
|
|
98
|
+
Ce qui va en base, c'est ce que produit son **usage** : exécutions, indices, retours, qui
|
|
99
|
+
appartiennent à `@mostajs/skill-library`. **Les deux ne se rangent pas au même endroit parce
|
|
100
|
+
qu'ils n'ont pas la même durée de vie : la fiche se relit, le journal s'entasse.**
|
|
101
|
+
|
|
102
|
+
**Pourquoi `succes` et `erreurs` sont les seuls champs requis en plus de l'énoncé.** Ce sont ceux
|
|
103
|
+
qu'on omet, et ceux qui servent. Exiger davantage ferait que les fiches ne s'écriraient pas ;
|
|
104
|
+
exiger moins produirait des titres.
|
|
105
|
+
|
|
106
|
+
**Pourquoi la conséquence est obligatoire.** « Ne pas oublier le périmètre » ne se retient pas ;
|
|
107
|
+
« sans lui, tout parent lit le dossier de tous les élèves » se retient. C'est la leçon de CWE, et
|
|
108
|
+
elle est ici contrainte par le code.
|
|
109
|
+
|
|
110
|
+
**Pourquoi la provenance a remplacé l'interdiction.** La première règle disait : *aucune fiche avant
|
|
111
|
+
un cas réel*. Elle aurait produit un catalogue vide dans six métiers où le savoir existe depuis des
|
|
112
|
+
décennies — un DTU, une fiche HACCP, un itinéraire technique sont des faits établis par une
|
|
113
|
+
profession entière. La règle a été déplacée sur le **verdict** : une `reference` suffit à entrer en
|
|
114
|
+
`propose` ; `eprouve` exige un `incident` ou un `terrain`. **La contrainte porte sur le galon,
|
|
115
|
+
jamais sur l'entrée.**
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 4 · Application localisée
|
|
120
|
+
|
|
121
|
+
Le corpus initial est tiré de la production de deux applications algériennes : un centre de langues
|
|
122
|
+
à Mostaganem et un restaurant.
|
|
123
|
+
|
|
124
|
+
**Six fiches éprouvées**, chacune datée et rattachée à son fichier : le périmètre pris pour une
|
|
125
|
+
capacité (trois emplois dans une même application) ; l'écriture d'un champ hors schéma ; la mise à
|
|
126
|
+
jour partielle qui écrase par `undefined` ; l'acquis effacé par la simple consultation ; l'écriture
|
|
127
|
+
faite hors de l'application vivante sur un stockage à image mémoire ; le calcul rendu sur des
|
|
128
|
+
données insuffisantes.
|
|
129
|
+
|
|
130
|
+
**Six fiches proposées**, adossées aux corpus des métiers visés : formulation au moindre coût
|
|
131
|
+
(problème du régime, Stigler 1945), transhumance apicole, ordonnancement de chantier sous
|
|
132
|
+
ressources finies, traçabilité de lot (HACCP), rotation culturale, diagnostic séquentiel de panne.
|
|
133
|
+
|
|
134
|
+
**Deux enseignements sont venus des métiers, et aucun domaine informatique ne les aurait donnés.**
|
|
135
|
+
|
|
136
|
+
Le premier : **un seuil de données s'exprime en cycles, jamais en jours.** Deux saisons complètes
|
|
137
|
+
font deux semaines en restauration, **deux ans** en grande culture, et **quelques jours par an** en
|
|
138
|
+
apiculture. Une fiche transverse a dû être corrigée pour cela.
|
|
139
|
+
|
|
140
|
+
Le second : **certains métiers posent leurs questions là où le logiciel ne tourne pas** — sur le
|
|
141
|
+
chantier, sur l'équipement embarqué. La fiche a gagné un champ pour distinguer *où la question se
|
|
142
|
+
pose* de *où elle se calcule*.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 5 · Correspondance avec l'image #14
|
|
147
|
+
|
|
148
|
+
L'image du résultat reprend les quatre stations de l'image de l'objectif — source, fiche,
|
|
149
|
+
projection, applications — et la flèche de retour de l'écart tracé. **Trois différences la
|
|
150
|
+
distinguent**, et elles sont l'histoire du cycle :
|
|
151
|
+
|
|
152
|
+
- la station 1 montre **trois** sources empilées, non plus un seul incident : c'est la correction de
|
|
153
|
+
la règle de provenance ;
|
|
154
|
+
- la fiche porte deux cases de plus, **provenance** et **verdict**, avec la mention « on ne se
|
|
155
|
+
décerne pas l'expérience » ;
|
|
156
|
+
- la bande de domaines compte **dix** pastilles au lieu de neuf : l'apiculture a été demandée en
|
|
157
|
+
cours de route, et elle s'est révélée le meilleur banc d'essai du refus.
|
|
158
|
+
|
|
159
|
+
L'encart chiffré — *12 fiches · 39 erreurs · 50 % éprouvé* — est absent de l'image de l'objectif :
|
|
160
|
+
la mesure de l'honnêteté est née avec le produit, pas avec le plan.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 6 · Discussion et projection d'utilisation
|
|
165
|
+
|
|
166
|
+
**Ce que le dispositif ne peut pas garantir.** La provenance est **déclarative**. Rien n'empêche
|
|
167
|
+
d'écrire `type: 'incident'` sur une origine inventée : le module contrôle la forme, jamais la
|
|
168
|
+
vérité. Le taux éprouvé mesure une **discipline**, pas une preuve. Cela doit être dit au client
|
|
169
|
+
comme à l'investisseur, faute de quoi le chiffre devient exactement ce qu'il prétend combattre.
|
|
170
|
+
|
|
171
|
+
**Un risque structurel assumé.** Une fiche est un module JavaScript : la charger, c'est l'exécuter.
|
|
172
|
+
Le choix « fichiers versionnés » apporte l'historique et la relecture ; il impose que **toute fiche
|
|
173
|
+
se revoie comme du code**. Un corpus déclaratif fermerait ce risque au prix de la validation au
|
|
174
|
+
montage — la question se rouvrira si des corpus tiers deviennent un cas d'usage.
|
|
175
|
+
|
|
176
|
+
**Trois usages se dessinent.** *Ouvrir un projet* en instanciant les fiches du domaine avant
|
|
177
|
+
d'écrire la première ligne. *Instruire un incident* en ajoutant l'erreur rencontrée à la fiche
|
|
178
|
+
existante plutôt qu'en créant une fiche de plus. *Argumenter devant un client* en montrant ce que
|
|
179
|
+
l'outil **refusera** de dire — la fiche apicole, qui admet que dix ans d'exploitation font dix
|
|
180
|
+
points incomparables, convainc un homme du métier plus sûrement qu'une promesse de précision.
|
|
181
|
+
|
|
182
|
+
**Ce qui décidera du succès** n'est pas le nombre de fiches, mais un indicateur unique : **combien
|
|
183
|
+
d'essais issus de la projection ont réellement échoué au moins une fois**. Une fiche qui n'a jamais
|
|
184
|
+
rien attrapé n'a jamais servi. Cet indicateur ne se lit pas dans le module — il se lit dans l'outil
|
|
185
|
+
de suivi, et c'est cohérent : le catalogue ne vaut que branché.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## 7 · Conclusion
|
|
190
|
+
|
|
191
|
+
Vingt ans de catalogues d'erreurs ont établi trois règles que personne n'avait appliquées aux
|
|
192
|
+
exigences : chaque entrée porte **sa conséquence** ; le corpus est nourri par des **faits** ; et il
|
|
193
|
+
ne sert que **branché à l'outillage**.
|
|
194
|
+
|
|
195
|
+
Un quatrième enseignement est venu des métiers eux-mêmes, et il ne figure dans aucun corpus
|
|
196
|
+
informatique : ce qui fait vivre un catalogue n'est pas la réutilisation à l'identique, **c'est
|
|
197
|
+
l'écart tracé**. L'agronomie adapte l'itinéraire technique au terroir et relève l'écart ; le
|
|
198
|
+
bâtiment amende le DTU par dérogation écrite. Le module l'impose : un affinage sans motif est
|
|
199
|
+
refusé.
|
|
200
|
+
|
|
201
|
+
Reste la question ouverte, et elle n'est pas technique : un catalogue vit s'il est **nourri**. Douze
|
|
202
|
+
fiches sont un début, pas une preuve. La réponse viendra du premier praticien — agriculteur,
|
|
203
|
+
conducteur de travaux, apiculteur — qui dira *« chez nous, la règle est différente parce que… »*.
|
|
204
|
+
Ce jour-là, l'écart sera enregistré avec son motif, et le catalogue aura commencé à travailler.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## 8 · Références
|
|
209
|
+
|
|
210
|
+
> ⚠️ **Sources citées par titre, auteur et année, sans URL ni pagination** : cet article a été
|
|
211
|
+
> rédigé hors ligne. Leur vérification est un contrôle **bloquant** du plan de publication (#9)
|
|
212
|
+
> avant toute diffusion.
|
|
213
|
+
|
|
214
|
+
1. Withall, S. — *Software Requirement Patterns*, Microsoft Press, 2007.
|
|
215
|
+
2. Mavin, A. *et al.* — *Easy Approach to Requirements Syntax (EARS)*, 2009.
|
|
216
|
+
3. ISO/IEC/IEEE 29148 — *Systems and software engineering — Requirements engineering*.
|
|
217
|
+
4. ISO/IEC/IEEE 29119 — *Software testing — Test documentation*.
|
|
218
|
+
5. MITRE — *Common Weakness Enumeration (CWE)* ; *CAPEC* ; *ATT&CK*.
|
|
219
|
+
6. OWASP — *Top 10*.
|
|
220
|
+
7. Nygard, M. — *Documenting Architecture Decisions*, 2011.
|
|
221
|
+
8. Aamodt, A. & Plaza, E. — *Case-Based Reasoning: Foundational Issues, Methodological Variations
|
|
222
|
+
and System Approaches*, AI Communications, 1994.
|
|
223
|
+
9. Rice, J. R. — *The Algorithm Selection Problem*, Advances in Computers, 1976.
|
|
224
|
+
10. Stigler, G. J. — *The Cost of Subsistence*, Journal of Farm Economics, 1945.
|
|
225
|
+
11. Dantzig, G. B. — travaux sur la méthode du simplexe, 1947 et suivants.
|
|
226
|
+
12. Codex Alimentarius — principes **HACCP**.
|
|
227
|
+
13. DTU et CCTG — documents techniques unifiés, marchés de travaux.
|
|
228
|
+
14. Documentation `@mostajs` : `DEVRULES.md`, `ro-pla`, `qa-engine`, `skill-library`,
|
|
229
|
+
`assistant-pilote`.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Domaine `acces` — ce qu'une permission ouvre, et ce qu'elle n'ouvre pas.
|
|
2
|
+
// @author Dr Hamid MADANI <drmdh@msn.com> · AGPL-3.0-or-later
|
|
3
|
+
import { defineKind } from '../src/kind.js';
|
|
4
|
+
|
|
5
|
+
export const kinds = [
|
|
6
|
+
defineKind({
|
|
7
|
+
ref: 'KIND-PERIMETRE-01',
|
|
8
|
+
domaine: 'acces',
|
|
9
|
+
enonce: 'Une permission ouvre une CAPACITÉ, jamais un PÉRIMÈTRE.',
|
|
10
|
+
utilisation: 'Toute application où un rôle agit sur des instances qui ne sont pas toutes siennes — dossiers, séances, plans de suivi, commandes, transitions d’automate.',
|
|
11
|
+
besoins: [{ nom: 'lien d’appartenance', forme: '(agent, instance) => bool' }],
|
|
12
|
+
succes: [
|
|
13
|
+
'le porteur agit sur les instances qui lui reviennent',
|
|
14
|
+
'il est refusé sur celles d’autrui, sans que le refus nomme l’instance',
|
|
15
|
+
'qui détient le domaine entier agit partout, sans lien à produire',
|
|
16
|
+
'une TRANSITION d’automate exige la permission ET le périmètre — jamais l’une des deux',
|
|
17
|
+
],
|
|
18
|
+
erreurs: [
|
|
19
|
+
{ titre: 'la capacité est prise pour le périmètre',
|
|
20
|
+
consequence: 'un enseignant pointe la séance d’un collègue, un parent lit le dossier d’un autre enfant — avec exactement les mêmes droits, et l’écran ne montre rien d’anormal' },
|
|
21
|
+
{ titre: 'le cumul de rôles desserre la garde',
|
|
22
|
+
consequence: 'ajouter un rôle ÉLARGIT le périmètre — c’est l’inverse de ce qu’une garde doit faire' },
|
|
23
|
+
{ titre: 'le champ porteur est vide',
|
|
24
|
+
consequence: '`undefined === undefined` vaut vrai : l’instance est donnée à tout le monde, et seuls les enregistrements incomplets sont touchés' },
|
|
25
|
+
{ titre: 'la capacité est accordée sans le périmètre',
|
|
26
|
+
consequence: 'l’écran s’ouvre sur une liste VIDE, sans message — la capacité sans le périmètre, c’est-à-dire rien' },
|
|
27
|
+
{ titre: 'le refus nomme l’instance refusée',
|
|
28
|
+
consequence: 'on énumère, de proche en proche, qui est inscrit' },
|
|
29
|
+
{ titre: 'la permission REMPLACE le périmètre sur une transition d’automate',
|
|
30
|
+
consequence: 'qui a le droit de faire avancer une commande le fait sur CELLE D’UN AUTRE — et l’historique, lui, est immuable' },
|
|
31
|
+
],
|
|
32
|
+
test: [
|
|
33
|
+
{ action: 'agir sur l’instance d’un autre porteur du même rôle', attendu: 'refus, sans nommer l’instance' },
|
|
34
|
+
{ action: 'cumuler un rôle borné et un rôle libre', attendu: 'reste borné' },
|
|
35
|
+
{ action: 'agir sur une instance dont le champ porteur est vide', attendu: 'refus' },
|
|
36
|
+
{ action: 'accorder la capacité sans le périmètre, puis lister', attendu: 'soit une liste utile, soit un message qui explique le vide' },
|
|
37
|
+
{ action: 'faire avancer l’instance d’un autre, en détenant la permission de transition', attendu: 'refus — la permission ne remplace pas le périmètre' },
|
|
38
|
+
],
|
|
39
|
+
verdict: 'eprouve',
|
|
40
|
+
origine: [
|
|
41
|
+
{ type: 'incident', source: 'ATC — presence.mjs, portail.mjs, coaching.mjs (3 emplois)', date: '2026-09-01' },
|
|
42
|
+
{ type: 'incident', source: 'ATC — secretariat porteur de `parents:read` n’ouvrait aucun dossier', date: '2026-09-01' },
|
|
43
|
+
{ type: 'incident', source: 'CRM/TRADING — gouvernance des transitions : « conserver le périmètre d’instance (assigné) COMBINÉ à la permission » (docs/AUDIT-PERMISSIONS-TRANSITIONS.md §5)', date: '2026-06-15' },
|
|
44
|
+
{ type: 'incident', source: 'LabTrax — « Brancher canScan PORTÉ SUR LA SÉANCE : l’enseignant ne pointe que sa séance ou son cours, jamais celle d’un autre »', date: '2026-08-31' },
|
|
45
|
+
{ type: 'reference', source: 'NIST RBAC / principe de moindre privilège' },
|
|
46
|
+
],
|
|
47
|
+
}),
|
|
48
|
+
];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Domaine `apprentissage` — ce qu'un apprenant acquiert, et ce qu'il ne doit pas perdre.
|
|
2
|
+
// @author Dr Hamid MADANI <drmdh@msn.com> · AGPL-3.0-or-later
|
|
3
|
+
import { defineKind } from '../src/kind.js';
|
|
4
|
+
|
|
5
|
+
export default defineKind({
|
|
6
|
+
ref: 'KIND-ACQUIS-01',
|
|
7
|
+
domaine: 'apprentissage',
|
|
8
|
+
enonce: 'Consulter un acquis ne doit jamais l’effacer.',
|
|
9
|
+
utilisation: 'Toute progression : leçon suivie, niveau atteint, étape franchie, certification.',
|
|
10
|
+
succes: ['rouvrir une étape terminée la laisse terminée', 'l’avancement ne décroît que sur un geste EXPLICITE'],
|
|
11
|
+
erreurs: [
|
|
12
|
+
{ titre: 'l’ouverture remet l’étape « en cours »',
|
|
13
|
+
consequence: 'l’apprenant relit son cours et son avancement retombe — il n’a aucun moyen de comprendre pourquoi, et il n’ose plus relire' },
|
|
14
|
+
{ titre: 'l’avancement compte des lignes de progression, pas des étapes existantes',
|
|
15
|
+
consequence: 'une étape retirée laisse sa trace : le fait dépasse le total, et le pourcentage franchit 100 %' },
|
|
16
|
+
{ titre: 'achever une étape inexistante est accepté',
|
|
17
|
+
consequence: 'un avancement est rangé qui ne compte nulle part — invisible à l’écran, et pourtant en base' },
|
|
18
|
+
],
|
|
19
|
+
test: [
|
|
20
|
+
{ action: 'achever une étape puis la rouvrir', attendu: 'l’avancement est inchangé' },
|
|
21
|
+
{ action: 'achever une étape inexistante', attendu: 'refus' },
|
|
22
|
+
],
|
|
23
|
+
verdict: 'eprouve',
|
|
24
|
+
origine: [{ type: 'incident', source: '@mostajs/elearning 0.1.0 — `start()` redescendait une leçon `done`', date: '2026-09-01' }],
|
|
25
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Domaine `decision` — d'où vient un nombre affiché, et ce qu'il vaut.
|
|
2
|
+
// @author Dr Hamid MADANI <drmdh@msn.com> · AGPL-3.0-or-later
|
|
3
|
+
import { defineKind } from '../src/kind.js';
|
|
4
|
+
|
|
5
|
+
export const kinds = [
|
|
6
|
+
defineKind({
|
|
7
|
+
ref: 'KIND-CHIFFRE-SANS-SOURCE-01',
|
|
8
|
+
domaine: 'decision',
|
|
9
|
+
enonce: 'Aucun chiffre n’est affiché sans que sa SOURCE ait été interrogée — et il mène à l’assiette qui le compose.',
|
|
10
|
+
utilisation: 'Tout tableau de bord, tout indicateur, toute vignette de comptage.',
|
|
11
|
+
besoins: [
|
|
12
|
+
{ nom: 'sources', forme: '[{ id, interroger() }] — déclarées, jamais écrites dans la page' },
|
|
13
|
+
{ nom: 'fraîcheur attendue', forme: 'seuil déclaré par source' },
|
|
14
|
+
],
|
|
15
|
+
succes: [
|
|
16
|
+
'chaque valeur affichée provient d’une source RÉELLEMENT interrogée',
|
|
17
|
+
'chaque compteur est cliquable vers la liste qui le compose',
|
|
18
|
+
'la fraîcheur de chaque valeur est visible, et au-delà du seuil la valeur bascule en « sans données »',
|
|
19
|
+
'trois états, et trois seulement : non branché · branché sans données · branché réel',
|
|
20
|
+
],
|
|
21
|
+
erreurs: [
|
|
22
|
+
{ titre: 'un nombre est écrit en dur, ou vient d’un jeu d’exemple',
|
|
23
|
+
consequence: 'la maquette devient la production sans que personne ne s’en aperçoive — le chiffre est stable, plausible, et ne décrit rien' },
|
|
24
|
+
{ titre: 'une source injoignable rend zéro',
|
|
25
|
+
consequence: 'zéro est un FAIT ; « je ne sais pas » n’en est pas un. On lit une chute d’activité là où il y a une panne de collecte' },
|
|
26
|
+
{ titre: 'la valeur périmée continue d’être servie',
|
|
27
|
+
consequence: 'le tableau de bord affiche avec le même aplomb une mesure d’hier et une d’il y a six mois' },
|
|
28
|
+
{ titre: 'le compteur ne mène nulle part',
|
|
29
|
+
consequence: 'un chiffre qu’on ne peut pas ouvrir ne se conteste pas — donc il ne se corrige jamais' },
|
|
30
|
+
{ titre: 'un second tableau de suivi est tenu à la main à côté',
|
|
31
|
+
consequence: 'les deux divergent, et c’est celui qu’on présente qui a tort' },
|
|
32
|
+
],
|
|
33
|
+
test: [
|
|
34
|
+
{ action: 'couper une source, puis afficher', attendu: '« sans données », jamais zéro' },
|
|
35
|
+
{ action: 'vieillir une valeur au-delà du seuil de fraîcheur', attendu: 'elle bascule en « sans données » et le dit' },
|
|
36
|
+
{ action: 'chercher dans le rendu un nombre absent des sources', attendu: 'aucun' },
|
|
37
|
+
{ action: 'suivre un compteur', attendu: 'il ouvre la liste filtrée qui le compose' },
|
|
38
|
+
],
|
|
39
|
+
verdict: 'eprouve',
|
|
40
|
+
origine: [
|
|
41
|
+
{ type: 'incident', source: 'CollabTrax — « N’afficher aucune valeur sans source interrogée : jamais de nombre en dur, jamais de valeur d’exemple » ; trois états ; fraîcheur ; compteur cliquable', date: '2026-08-03' },
|
|
42
|
+
{ type: 'incident', source: 'ATC — le pilotage compose @mostajs/reporting ; la vue ne recalcule aucun total (T-PIL-10)', date: '2026-09-01' },
|
|
43
|
+
],
|
|
44
|
+
}),
|
|
45
|
+
|
|
46
|
+
defineKind({
|
|
47
|
+
ref: 'KIND-REFUS-LISIBLE-01',
|
|
48
|
+
domaine: 'decision',
|
|
49
|
+
enonce: 'Un refus NOMME sa cause et offre une issue — sauf quand la nommer renseigne celui qui n’y a pas droit.',
|
|
50
|
+
utilisation: 'Tout refus rendu à un humain : garde d’accès, validation, calcul impossible, quota.',
|
|
51
|
+
succes: [
|
|
52
|
+
'le refus dit CE QUI MANQUE, chiffré quand c’est un compte',
|
|
53
|
+
'il dit ce qu’il faut FAIRE pour le lever',
|
|
54
|
+
'lorsqu’il porte sur une instance interdite, il ne révèle NI son existence NI son contenu',
|
|
55
|
+
],
|
|
56
|
+
erreurs: [
|
|
57
|
+
{ titre: 'le refus est générique — « action impossible », « indisponible »',
|
|
58
|
+
consequence: 'l’utilisateur ressaie à l’identique, indéfiniment. « Pas disponible » n’apprend rien ; « il manque onze jours » se corrige' },
|
|
59
|
+
{ titre: 'le refus désigne la MAUVAISE cause',
|
|
60
|
+
consequence: 'le pire des cas : on cherche pendant des heures du côté qu’on nous a montré. Un « code refusé » sur un identifiant inconnu envoie ressaisir un code déjà bon' },
|
|
61
|
+
{ titre: 'le refus nomme l’instance à qui n’y a pas droit',
|
|
62
|
+
consequence: 'confirmer l’existence renseigne déjà : on énumère, de proche en proche, qui est inscrit' },
|
|
63
|
+
{ titre: 'le refus n’offre aucune issue',
|
|
64
|
+
consequence: 'il devient une impasse : l’utilisateur appelle, et le refus coûte plus cher que l’action' },
|
|
65
|
+
{ titre: 'le refus n’est pas tracé',
|
|
66
|
+
consequence: 'les tentatives répétées ne se voient pas — ni la gêne d’un utilisateur légitime, ni l’insistance d’un autre' },
|
|
67
|
+
],
|
|
68
|
+
test: [
|
|
69
|
+
{ action: 'refuser sur donnée manquante', attendu: 'le manque est chiffré et l’issue est dite' },
|
|
70
|
+
{ action: 'refuser l’accès à l’instance d’autrui', attendu: 'ni son nom ni son identifiant n’apparaissent dans la réponse' },
|
|
71
|
+
{ action: 'se tromper d’identifiant', attendu: 'le message couvre les DEUX causes sans dire laquelle — et ne désigne pas la mauvaise' },
|
|
72
|
+
],
|
|
73
|
+
verdict: 'eprouve',
|
|
74
|
+
origine: [
|
|
75
|
+
{ type: 'incident', source: 'LabTrax — « DIRE LA VRAIE RAISON D’UN REFUS, et offrir une issue »', date: '2026-08-31' },
|
|
76
|
+
{ type: 'incident', source: 'RestoTrax — « Identifiant ou code refusé » : le message désignait le CODE, on ressaisissait le bon indéfiniment', date: '2026-09-02' },
|
|
77
|
+
{ type: 'incident', source: 'ATC — le refus du portail ne nomme ni l’élève ni son identifiant (T-POR-2)', date: '2026-09-01' },
|
|
78
|
+
],
|
|
79
|
+
}),
|
|
80
|
+
];
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Domaine `decision` — ce qu'on peut conclure, et à partir de quand.
|
|
2
|
+
// @author Dr Hamid MADANI <drmdh@msn.com> · AGPL-3.0-or-later
|
|
3
|
+
import { defineKind } from '../src/kind.js';
|
|
4
|
+
|
|
5
|
+
export const kinds = [
|
|
6
|
+
defineKind({
|
|
7
|
+
ref: 'KIND-DONNEE-INSUFFISANTE-01',
|
|
8
|
+
domaine: 'decision',
|
|
9
|
+
enonce: 'Un calcul dont la donnée est insuffisante REFUSE, et chiffre ce qui lui manque.',
|
|
10
|
+
utilisation: 'Tout indicateur, toute prévision, tout conseil tiré d’un historique.',
|
|
11
|
+
besoins: [
|
|
12
|
+
{ nom: 'volume observé', forme: 'nombre de CYCLES observés' },
|
|
13
|
+
{ nom: 'seuil', forme: 'valeur déclarée, éditable — jamais une constante' },
|
|
14
|
+
],
|
|
15
|
+
succes: [
|
|
16
|
+
'sous le seuil, le calcul refuse et NOMME ce qui manque, chiffré',
|
|
17
|
+
'le seuil est une valeur déclarée, visible et modifiable',
|
|
18
|
+
'la condition est réévaluée à chaque lecture, jamais une fois pour toutes',
|
|
19
|
+
'trois états sont distingués, et trois seulement : NON BRANCHÉ (aucune source) · BRANCHÉ SANS DONNÉES (source vide ou périmée) · BRANCHÉ RÉEL',
|
|
20
|
+
],
|
|
21
|
+
erreurs: [
|
|
22
|
+
{ titre: 'un chiffre est rendu sur trop peu de points',
|
|
23
|
+
consequence: 'il a l’air sérieux, il est tiré de rien, et c’est celui qu’on présente au conseil' },
|
|
24
|
+
{ titre: 'le refus dit « indisponible » sans chiffrer',
|
|
25
|
+
consequence: '« pas disponible » n’apprend rien ; « il manque 11 jours » se corrige' },
|
|
26
|
+
{ titre: 'la condition est évaluée à l’activation seulement',
|
|
27
|
+
consequence: 'activée en janvier sur des données saines, elle conseille encore en mai sur un référentiel vidé — avec la même assurance' },
|
|
28
|
+
{ titre: 'le seuil est exprimé en JOURS',
|
|
29
|
+
consequence: 'il ment dès que le cycle change d’échelle : deux saisons font deux semaines en restauration, deux ANS en grande culture, et une poignée de jours par an en apiculture' },
|
|
30
|
+
{ titre: 'le seuil est écrit en dur',
|
|
31
|
+
consequence: 'personne ne le relit, et il finit tenu pour une loi de la nature' },
|
|
32
|
+
{ titre: '« aucune source » et « source vide » sont confondus',
|
|
33
|
+
consequence: 'l’exploitant ne sait pas s’il doit BRANCHER quelque chose ou SAISIR quelque chose. Ce sont deux gestes différents, et l’écran les présente pareil' },
|
|
34
|
+
],
|
|
35
|
+
test: [
|
|
36
|
+
{ action: 'demander un calcul sous le seuil', attendu: 'refus chiffrant ce qui manque' },
|
|
37
|
+
{ action: 'vider la donnée sous un calcul déjà activé', attendu: 'il cesse de répondre et le DIT' },
|
|
38
|
+
{ action: 'exprimer le seuil pour un domaine à cycle annuel', attendu: 'le seuil est en cycles, pas en jours' },
|
|
39
|
+
],
|
|
40
|
+
verdict: 'eprouve',
|
|
41
|
+
origine: [
|
|
42
|
+
{ type: 'incident', source: 'RestoTrax — 237 transitions dormaient au journal sans que rien ne le dise', date: '2026-08-30' },
|
|
43
|
+
{ type: 'incident', source: 'ATC — les 4 questions de l’assistant chiffrent leur manque', date: '2026-09-01' },
|
|
44
|
+
{ type: 'incident', source: 'CollabTrax — « Afficher trois états et trois seulement : non branché / branché sans données / branché réel »', date: '2026-08-03' },
|
|
45
|
+
{ type: 'reference', source: 'Prévision : deux saisons complètes exigées avant toute méthode saisonnière' },
|
|
46
|
+
],
|
|
47
|
+
}),
|
|
48
|
+
|
|
49
|
+
defineKind({
|
|
50
|
+
ref: 'KIND-ECRITURE-GARDEE-01',
|
|
51
|
+
domaine: 'decision',
|
|
52
|
+
enonce: 'Une écriture déclenchée par une machine s’obtient en DEUX temps : un aperçu inerte, puis une confirmation explicite.',
|
|
53
|
+
utilisation: 'Tout geste qu’un assistant, un robot ou une règle automatique produit et qui modifie l’état du métier.',
|
|
54
|
+
besoins: [
|
|
55
|
+
{ nom: 'catalogue des actions autorisées', forme: '[{ code, paramètres attendus }]' },
|
|
56
|
+
{ nom: 'port d’audit', forme: '(acte, acteur, résultat) => void' },
|
|
57
|
+
],
|
|
58
|
+
succes: [
|
|
59
|
+
'sans confirmation, l’appel rend un APERÇU et n’écrit RIEN',
|
|
60
|
+
'avec confirmation ET permission, l’écriture a lieu et elle est auditée',
|
|
61
|
+
'le brouillon produit est INERTE tant qu’il n’est pas activé',
|
|
62
|
+
'le refus est audité comme l’accord',
|
|
63
|
+
],
|
|
64
|
+
erreurs: [
|
|
65
|
+
{ titre: 'l’aperçu écrit déjà quelque chose',
|
|
66
|
+
consequence: 'l’utilisateur croit regarder ; il a déjà agi. C’est la faute la plus grave du dispositif, parce qu’elle détruit la confiance dans tous les aperçus suivants' },
|
|
67
|
+
{ titre: 'la garde est posée dans la VUE',
|
|
68
|
+
consequence: 'un second appelant — interface de programmation, tâche planifiée, autre écran — la contourne sans le savoir. Un garde posé dans la vue se perd à la vue suivante' },
|
|
69
|
+
{ titre: 'la confirmation vaut pour toute la session',
|
|
70
|
+
consequence: 'un acte préparé il y a vingt minutes s’exécute sur un contexte qui a changé' },
|
|
71
|
+
{ titre: 'seuls les succès sont audités',
|
|
72
|
+
consequence: 'un refus tu laisse croire que rien n’a été tenté — et l’on ne voit pas les tentatives répétées' },
|
|
73
|
+
{ titre: 'l’action exécutée n’est pas celle qui a été prévisualisée',
|
|
74
|
+
consequence: 'l’aperçu devient une formalité : il montre A, il applique B, et personne ne le remarque avant longtemps' },
|
|
75
|
+
],
|
|
76
|
+
test: [
|
|
77
|
+
{ action: 'demander l’acte SANS confirmation, puis compter les lignes du métier avant et après', attendu: 'un aperçu, et AUCUN écart' },
|
|
78
|
+
{ action: 'confirmer sans détenir la permission', attendu: 'refus, audité' },
|
|
79
|
+
{ action: 'confirmer un aperçu produit sur un contexte depuis modifié', attendu: 'refus ou nouvel aperçu — jamais l’exécution silencieuse' },
|
|
80
|
+
],
|
|
81
|
+
verdict: 'eprouve',
|
|
82
|
+
origine: [
|
|
83
|
+
{ type: 'incident', source: 'CRM/TRADING — copilote : transitions et réassignations, aperçu sans --confirm puis exécution (CARNET motif #2)', date: '2026-06-13' },
|
|
84
|
+
{ type: 'incident', source: 'RestoTrax — l’assistant-pilote n’a que deux écritures, et ce sont des DÉCISIONS (TPIL-7)', date: '2026-08-30' },
|
|
85
|
+
{ type: 'incident', source: 'ATC — l’écran de l’assistant ne porte aucune action métier (T-ASS-9)', date: '2026-09-01' },
|
|
86
|
+
],
|
|
87
|
+
}),
|
|
88
|
+
];
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Domaine `donnees` — ce qui s'écrit vraiment, et ce qui disparaît en silence.
|
|
2
|
+
// @author Dr Hamid MADANI <drmdh@msn.com> · AGPL-3.0-or-later
|
|
3
|
+
import { defineKind } from '../src/kind.js';
|
|
4
|
+
|
|
5
|
+
export const kinds = [
|
|
6
|
+
defineKind({
|
|
7
|
+
ref: 'KIND-ECRITURE-HORS-SCHEMA-01',
|
|
8
|
+
domaine: 'donnees',
|
|
9
|
+
enonce: 'Un champ écrit sans être déclaré au schéma disparaît en base, et nulle part ailleurs.',
|
|
10
|
+
utilisation: 'Toute application dont le stockage est déclaré (ORM, schéma, migration) et dont les essais tournent en mémoire.',
|
|
11
|
+
succes: [
|
|
12
|
+
'le champ écrit est relu après un redémarrage',
|
|
13
|
+
'les essais qui écrivent ce champ tournent AUSSI sur le stockage réel',
|
|
14
|
+
],
|
|
15
|
+
erreurs: [
|
|
16
|
+
{ titre: 'l’essai tourne en mémoire, la production sur schéma',
|
|
17
|
+
consequence: 'la suite est verte et la donnée est perdue — c’est la divergence la plus coûteuse, parce qu’elle rassure' },
|
|
18
|
+
{ titre: 'le champ est ajouté au code sans l’être au schéma',
|
|
19
|
+
consequence: 'aucune erreur : l’écriture est acceptée puis ignorée' },
|
|
20
|
+
{ titre: 'la liste des schémas est tenue à la main',
|
|
21
|
+
consequence: 'un module gagne une entité, la table n’est jamais créée, et rien ne le dit jusqu’au premier enregistrement' },
|
|
22
|
+
{ titre: 'le champ est ajouté au schéma, mais la migration ne SAIT PAS altérer une table existante',
|
|
23
|
+
consequence: 'le schéma est juste, le code est juste, et la colonne n’existe pas en base : sous sqljs, la migration CRÉE les tables neuves et n’ALTÈRE pas les anciennes. Le symptôme est identique à un champ non déclaré, et la cause est ailleurs — d’où des heures perdues à relire un schéma correct' },
|
|
24
|
+
],
|
|
25
|
+
test: [
|
|
26
|
+
{ action: 'écrire un champ, redémarrer, relire', attendu: 'la valeur est là' },
|
|
27
|
+
{ action: 'écrire un champ absent du schéma', attendu: 'refus ou avertissement — jamais une acceptation muette' },
|
|
28
|
+
{ action: 'ajouter une colonne à une entité EXISTANTE, migrer, écrire, relire', attendu: 'la valeur revient — sinon la migration n’altère pas, et il faut une table annexe' },
|
|
29
|
+
],
|
|
30
|
+
verdict: 'eprouve',
|
|
31
|
+
origine: [
|
|
32
|
+
{ type: 'incident', source: 'ATC — moyen de paiement écrit hors schéma de facture', date: '2026-08-31' },
|
|
33
|
+
{ type: 'incident', source: '@mostajs/coaching — `bookingId` retenu sans être déclaré', date: '2026-09-01' },
|
|
34
|
+
{ type: 'incident', source: 'CRM/TRADING — sous sqljs la migration ne fait pas d’ALTER ; parade retenue : table dédiée (`workflow_layout`) — CARNET motif #5', date: '2026-06-13' },
|
|
35
|
+
],
|
|
36
|
+
}),
|
|
37
|
+
|
|
38
|
+
defineKind({
|
|
39
|
+
ref: 'KIND-MAJ-PARTIELLE-01',
|
|
40
|
+
domaine: 'donnees',
|
|
41
|
+
enonce: 'Une mise à jour partielle ne doit écrire QUE ce qui est fourni.',
|
|
42
|
+
utilisation: 'Tout formulaire où l’on corrige un champ sans ressaisir les autres.',
|
|
43
|
+
succes: ['corriger un champ laisse les autres intacts', 'effacer un champ est un geste EXPLICITE, distinct de ne pas le fournir'],
|
|
44
|
+
erreurs: [
|
|
45
|
+
{ titre: '`{...existant, champ: undefined}` est écrit tel quel',
|
|
46
|
+
consequence: 'le champ non fourni est ÉCRASÉ — on corrige une note et l’on perd le compte-rendu, sans erreur ni trace' },
|
|
47
|
+
{ titre: 'le formulaire envoie une chaîne vide pour un champ non saisi',
|
|
48
|
+
consequence: 'le module respecte le contrat, et c’est l’application qui détruit la donnée' },
|
|
49
|
+
],
|
|
50
|
+
test: [
|
|
51
|
+
{ action: 'renseigner deux champs, puis n’en corriger qu’un', attendu: 'l’autre survit' },
|
|
52
|
+
{ action: 'envoyer une chaîne vide pour un champ non saisi', attendu: 'le champ n’est pas écrasé' },
|
|
53
|
+
],
|
|
54
|
+
verdict: 'eprouve',
|
|
55
|
+
origine: [{ type: 'incident', source: '@mostajs/coaching — `report()` écrasait les notes', date: '2026-09-01' }],
|
|
56
|
+
}),
|
|
57
|
+
|
|
58
|
+
defineKind({
|
|
59
|
+
ref: 'KIND-ECRITURE-HORS-APPLICATION-01',
|
|
60
|
+
domaine: 'donnees',
|
|
61
|
+
enonce: 'Sur un stockage à image mémoire, une écriture faite hors de l’application vivante est écrasée.',
|
|
62
|
+
utilisation: 'Toute reprise de données, migration ou vérification sur une base servie en image mémoire (sqljs, SQLite embarqué, base fichier).',
|
|
63
|
+
succes: ['la reprise est relue dans un NOUVEAU processus, après que l’application a écrit', 'le script refuse de s’exécuter tant que l’application répond'],
|
|
64
|
+
erreurs: [
|
|
65
|
+
{ titre: 'le script annonce « n lignes reprises » et son travail disparaît',
|
|
66
|
+
consequence: 'l’application réécrit le fichier depuis SON image mémoire, qui n’a jamais vu la reprise — sans erreur, et avec un délai qui peut être de plusieurs heures' },
|
|
67
|
+
{ titre: 'la reprise est vérifiée dans le même processus',
|
|
68
|
+
consequence: 'elle paraît réussie : c’est la mémoire du script qu’on relit, pas la base' },
|
|
69
|
+
],
|
|
70
|
+
test: [
|
|
71
|
+
{ action: 'lancer une reprise application vivante', attendu: 'refus explicite' },
|
|
72
|
+
{ action: 'reprendre application arrêtée, redémarrer, relire ailleurs', attendu: 'la reprise tient' },
|
|
73
|
+
],
|
|
74
|
+
verdict: 'eprouve',
|
|
75
|
+
origine: [{ type: 'incident', source: 'ATC — reprise des notes effacée, certificat jamais persisté (DB_DIALECT=sqljs)', date: '2026-09-02' }],
|
|
76
|
+
}),
|
|
77
|
+
|
|
78
|
+
defineKind({
|
|
79
|
+
ref: 'KIND-SORTIE-GENEREE-01',
|
|
80
|
+
domaine: 'donnees',
|
|
81
|
+
enonce: 'Une sortie GÉNÉRÉE n’entre dans le système qu’après validation contre un catalogue DÉCLARÉ.',
|
|
82
|
+
utilisation: 'Tout ce qu’un modèle de langage, un moteur de règles ou un extracteur produit sous forme structurée.',
|
|
83
|
+
besoins: [{ nom: 'catalogue', forme: 'registre déclaré des valeurs autorisées — événements, conditions, actions, champs' }],
|
|
84
|
+
succes: [
|
|
85
|
+
'une valeur hors catalogue est REFUSÉE, et le refus la nomme',
|
|
86
|
+
'le catalogue est la source UNIQUE : l’invite, le validateur et les exemples en découlent',
|
|
87
|
+
'une hallucination devient une erreur rattrapable, pas une donnée',
|
|
88
|
+
],
|
|
89
|
+
erreurs: [
|
|
90
|
+
{ titre: 'on fait confiance au texte produit',
|
|
91
|
+
consequence: 'une valeur inventée entre dans le système. Elle est plausible, elle se propage, et on la découvre là où elle fait du dégât — pas là où elle est née' },
|
|
92
|
+
{ titre: 'le catalogue est décrit dans l’invite mais n’est pas appliqué à la SORTIE',
|
|
93
|
+
consequence: 'l’invite dit une chose et le code accepte tout : la barrière n’existe que dans la conversation' },
|
|
94
|
+
{ titre: 'deux listes coexistent — une pour l’invite, une pour la validation',
|
|
95
|
+
consequence: 'elles divergent, et c’est toujours la validation qui perd : on élargit le validateur pour débloquer' },
|
|
96
|
+
{ titre: 'le refus ne nomme pas la valeur fautive',
|
|
97
|
+
consequence: 'irrattrapable : ni l’utilisateur ni le modèle ne savent quoi corriger' },
|
|
98
|
+
],
|
|
99
|
+
test: [
|
|
100
|
+
{ action: 'produire une valeur absente du catalogue', attendu: 'refus nommant la valeur ET le catalogue attendu' },
|
|
101
|
+
{ action: 'retirer une entrée du catalogue', attendu: 'l’invite et le validateur changent ENSEMBLE — une seule source' },
|
|
102
|
+
],
|
|
103
|
+
verdict: 'eprouve',
|
|
104
|
+
origine: [
|
|
105
|
+
{ type: 'incident', source: 'CRM/TRADING — validateRule de l’éditeur ECA ; normalizeOffer rejette une offre sans supplier/sourceUrl (CARNET motif #3)', date: '2026-06-13' },
|
|
106
|
+
],
|
|
107
|
+
}),
|
|
108
|
+
];
|