@sigloch/contracts 9.1.0 → 10.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.
Files changed (40) hide show
  1. package/dist/se/ao-rules.d.ts +12 -12
  2. package/dist/se/ao-rules.js +88 -225
  3. package/dist/se/conformance-rules.d.ts +12 -0
  4. package/dist/se/conformance-rules.js +6 -6
  5. package/dist/se/cr-quality-rules.js +75 -58
  6. package/dist/se/evaluate-all.d.ts +4 -2
  7. package/dist/se/evaluate-all.js +61 -24
  8. package/dist/se/fchain-quality-rules.d.ts +0 -1
  9. package/dist/se/fchain-quality-rules.js +0 -44
  10. package/dist/se/flat-graph.d.ts +9 -1
  11. package/dist/se/flat-graph.js +15 -6
  12. package/dist/se/grammar-snapshot.d.ts +9 -5
  13. package/dist/se/grammar-snapshot.js +250 -15
  14. package/dist/se/index.d.ts +6 -3
  15. package/dist/se/index.js +14 -3
  16. package/dist/se/meta-model.d.ts +47 -0
  17. package/dist/se/meta-model.js +52 -5
  18. package/dist/se/metric-rules.d.ts +20 -1
  19. package/dist/se/metric-rules.js +97 -58
  20. package/dist/se/module-crossings.d.ts +102 -0
  21. package/dist/se/module-crossings.js +196 -0
  22. package/dist/se/near-duplicate-rules.d.ts +16 -24
  23. package/dist/se/near-duplicate-rules.js +21 -92
  24. package/dist/se/ontology.d.ts +0 -22
  25. package/dist/se/ontology.js +0 -2
  26. package/dist/se/policy.d.ts +6 -0
  27. package/dist/se/policy.js +53 -2
  28. package/dist/se/quality-rules.d.ts +18 -0
  29. package/dist/se/quality-rules.js +51 -9
  30. package/dist/se/readiness.d.ts +25 -3
  31. package/dist/se/readiness.js +39 -21
  32. package/dist/se/rule-help.d.ts +52 -0
  33. package/dist/se/rule-help.js +342 -0
  34. package/dist/se/rules.d.ts +6 -0
  35. package/dist/se/rules.js +303 -125
  36. package/dist/se/schema-quality-rules.d.ts +0 -1
  37. package/dist/se/schema-quality-rules.js +7 -28
  38. package/dist/se/similarity.d.ts +61 -0
  39. package/dist/se/similarity.js +116 -0
  40. package/package.json +4 -2
@@ -23,14 +23,37 @@ const measurablePattern = /(\d+[\s]*(ms|s|sec|min|%|percent|byte|MB|GB|times|x|s
23
23
  function reqElements(graph) {
24
24
  return graph.elements.filter(e => e.type === 'REQ');
25
25
  }
26
+ /**
27
+ * CR-SM-275: `description` ist im Zod-Schema Pflicht, aber die Regeln bekommen Graphen aus
28
+ * Store/Import ohne Re-Parse — dort fehlt das Feld. `req.description.trim()` warf dann
29
+ * `TypeError` und riss `evaluateAllRules` ab (gemessen am kadjar-Graphen, Spike CR-GC-438 §7).
30
+ * EIN Normalisierungspunkt statt eines Guards je Fundstelle: eine fehlende Beschreibung ist
31
+ * die leere Beschreibung — ein BEFUND (BQ-06/BQ-07 melden sie), kein Absturz.
32
+ */
33
+ /**
34
+ * CR-SM-285: `?? ''` faengt nur `null`/`undefined`. Ein Graph aus einer fremden Quelle (Import,
35
+ * fremdes Tool, handgeschriebene Fixture) kann `description` als Zahl, Objekt oder Array tragen —
36
+ * dann warf `.trim()` und `evaluateAllRules` STARB, statt zu urteilen. Am Gate heisst das:
37
+ * Stacktrace statt `block`-Verdict, der Aufrufer sieht kein Urteil.
38
+ *
39
+ * Gemessen vor dem Fix: `null` ok, `42`/`{}`/`[]`/`true` -> "descriptionOf(...).trim is not a
40
+ * function". Vier von fuenf Typen.
41
+ *
42
+ * Nicht-Strings werden zu `''` — also behandelt wie "keine Beschreibung". Das ist die richtige
43
+ * Deutung: ein Objekt IST keine Beschreibung, und die Regel soll das melden statt zu raten oder
44
+ * zu sterben.
45
+ */
46
+ function descriptionOf(el) {
47
+ return typeof el.description === 'string' ? el.description : '';
48
+ }
26
49
  // ---------------------------------------------------------------------------
27
50
  // BQ-01 Unambiguous — detect weasel words in REQ descriptions
28
51
  // ---------------------------------------------------------------------------
29
52
  export function bq01Unambiguous(graph) {
30
53
  return reqElements(graph)
31
- .filter(req => weaselPattern.test(req.description))
54
+ .filter(req => weaselPattern.test(descriptionOf(req)))
32
55
  .map(req => {
33
- const match = req.description.match(weaselPattern);
56
+ const match = descriptionOf(req).match(weaselPattern);
34
57
  return {
35
58
  rule_id: 'BQ-01',
36
59
  severity: 'warning',
@@ -50,7 +73,7 @@ export function bq01Unambiguous(graph) {
50
73
  // ---------------------------------------------------------------------------
51
74
  export function bq02Verifiable(graph) {
52
75
  return reqElements(graph)
53
- .filter(req => !measurablePattern.test(req.description))
76
+ .filter(req => !measurablePattern.test(descriptionOf(req)))
54
77
  .map(req => ({
55
78
  rule_id: 'BQ-02',
56
79
  severity: 'warning',
@@ -85,6 +108,24 @@ export function setBQ04SimilarityMatrix(data) {
85
108
  /**
86
109
  * BQ-04 checks for duplicate / near-duplicate requirements using
87
110
  * pre-computed embedding similarity. Returns [] when no matrix is set.
111
+ *
112
+ * CR-SM-286: **bewusst NICHT angeschlossen — anders als ND-01/ND-02.**
113
+ *
114
+ * Die Naht ist dieselbe und sie ist genauso tot: `setBQ04SimilarityMatrix()` ruft im gesamten
115
+ * Familienbaum niemand (CR-SM-278, erneut geprueft). Der Unterschied liegt in der Eingabe. ND-01
116
+ * und ND-02 nennen deterministische Formeln ueber Graphinhalt (Jaccard ueber Beschreibung,
117
+ * Verb, io-Topologie, Felder) — die konnten nach `similarity.ts` wandern und tun dort dasselbe.
118
+ * BQ-04 verlangt laut eigener Zeile "pre-computed EMBEDDING similarity", und Embeddings kann ein
119
+ * reines Vertragspaket nicht berechnen: kein Modell, kein Netz, kein Zufall.
120
+ *
121
+ * Ein Ersatzmass haette ich erfinden muessen. Ein Versuch mit 0.7*Beschreibung + 0.3*Name lief:
122
+ * **0 Befunde an allen neun Familiengraphen** und 4950 an einer templatierten Fixture — also
123
+ * genau die zwei Gate-7-Ausreisser zugleich ("0 Befunde am Selbstmodell" und "quadratisch mit
124
+ * der Graphgroesse"). Erfundene Gewichte ohne Messung sind keine Reparatur.
125
+ *
126
+ * Damit ist BQ-04 der naechste AO-D03-Fall: entweder eine Eingabe, die der Host liefern MUSS
127
+ * (dann gehoert die Regel nicht in ein reines Paket), oder streichen. Das ist eine
128
+ * Grammatik-Entscheidung — `se-grammar-review`, eigener CR, nicht hier nebenbei.
88
129
  */
89
130
  export function bq04Necessary(graph) {
90
131
  if (!_bq04Matrix)
@@ -141,7 +182,7 @@ const conformingPatternDE = /\b(soll|muss|darf nicht)\s+\w+/i;
141
182
  export function bq06Conforming(graph) {
142
183
  return reqElements(graph)
143
184
  .filter(req => {
144
- const desc = req.description.trim();
185
+ const desc = descriptionOf(req).trim();
145
186
  return !conformingPattern.test(desc) && !conformingPatternDE.test(desc);
146
187
  })
147
188
  .map(req => ({
@@ -174,17 +215,18 @@ export function bq07Complete(graph) {
174
215
  // zulaessig ist. Das ist die Fehlmessung und deshalb R-18/error; das blosse Fehlen der
175
216
  // Angabe ist ein Vollstaendigkeitssignal und deshalb hier/warning — dieselbe Trennung, die
176
217
  // CR-SM-262 fuer RC-06 begruendet hat.
177
- const isIncomplete = (req) => req.description.trim().length < BQ07_MIN_DESC_LENGTH ||
178
- placeholderPattern.test(req.description) ||
218
+ const isIncomplete = (req) => descriptionOf(req).trim().length < BQ07_MIN_DESC_LENGTH ||
219
+ placeholderPattern.test(descriptionOf(req)) ||
179
220
  normalizeReqKinds(req.kinds).length === 0;
180
221
  return reqElements(graph)
181
222
  .filter(isIncomplete)
182
223
  .map(req => {
224
+ const desc = descriptionOf(req);
183
225
  const reasons = [];
184
- if (req.description.trim().length < BQ07_MIN_DESC_LENGTH) {
185
- reasons.push(`description too short (${req.description.trim().length}/${BQ07_MIN_DESC_LENGTH} chars)`);
226
+ if (desc.trim().length < BQ07_MIN_DESC_LENGTH) {
227
+ reasons.push(`description too short (${desc.trim().length}/${BQ07_MIN_DESC_LENGTH} chars)`);
186
228
  }
187
- if (placeholderPattern.test(req.description)) {
229
+ if (placeholderPattern.test(desc)) {
188
230
  reasons.push('contains placeholder');
189
231
  }
190
232
  if (normalizeReqKinds(req.kinds).length === 0) {
@@ -9,24 +9,24 @@
9
9
  */
10
10
  import { z } from 'zod/v4';
11
11
  export declare const ReadinessDimension: z.ZodEnum<{
12
+ schema: "schema";
12
13
  req: "req";
13
14
  uc: "uc";
14
15
  arch: "arch";
15
16
  alloc: "alloc";
16
17
  ver: "ver";
17
- schema: "schema";
18
18
  cr: "cr";
19
19
  ms: "ms";
20
20
  }>;
21
21
  export type ReadinessDimensionType = z.infer<typeof ReadinessDimension>;
22
22
  export declare const ReadinessScore: z.ZodObject<{
23
23
  dimension: z.ZodEnum<{
24
+ schema: "schema";
24
25
  req: "req";
25
26
  uc: "uc";
26
27
  arch: "arch";
27
28
  alloc: "alloc";
28
29
  ver: "ver";
29
- schema: "schema";
30
30
  cr: "cr";
31
31
  ms: "ms";
32
32
  }>;
@@ -49,12 +49,12 @@ export type ReadinessScoreType = z.infer<typeof ReadinessScore>;
49
49
  export declare const ReadinessReport: z.ZodObject<{
50
50
  scores: z.ZodArray<z.ZodObject<{
51
51
  dimension: z.ZodEnum<{
52
+ schema: "schema";
52
53
  req: "req";
53
54
  uc: "uc";
54
55
  arch: "arch";
55
56
  alloc: "alloc";
56
57
  ver: "ver";
57
- schema: "schema";
58
58
  cr: "cr";
59
59
  ms: "ms";
60
60
  }>;
@@ -67,6 +67,28 @@ export declare const ReadinessReport: z.ZodObject<{
67
67
  timestamp: z.ZodISODateTime;
68
68
  }, z.core.$strip>;
69
69
  export type ReadinessReportType = z.infer<typeof ReadinessReport>;
70
+ /**
71
+ * CR-SM-305 — welche Profile in die readiness-Zahlen eingehen, und warum `conformance` nicht.
72
+ *
73
+ * Der Nenner jeder Dimension ist `Σ (Elemente der Grundgesamtheit)` ueber die Regeln der
74
+ * Dimension (`readiness-compute.ts`). Eine Regel, die DEKLARIERT, aber nicht AUSGEWERTET wird,
75
+ * traegt damit zum Nenner bei und liefert null Verstoesse — der Score STEIGT, weil eine
76
+ * Pruefung nicht gelaufen ist. Dieselbe Fail-open-Klasse wie ND-01/02 vor CR-SM-286, nur an der
77
+ * Stelle, die am lautesten gelesen wird.
78
+ *
79
+ * Gemessen ueber vier Familien-Repos, was die sechs RC-Regeln in `arch`/`ver`/`schema`
80
+ * geschenkt haetten: graph-view-edit `schema` +5,0 Punkte (Nenner 24 → 40), graphify `arch`
81
+ * +2,1 und `ver` +1,8, alles Uebrige ≤ 0,2. Der Ausschlag sitzt genau dort, wo die Zahl am
82
+ * meisten wiegt — in der kleinen Dimension.
83
+ *
84
+ * Deshalb steht keine RC-ID in `RULE_TO_DIMENSION` oder `RULE_TO_PHASE`. Das ist keine Luecke,
85
+ * sondern die Aussage „nicht ausgewertet, also weder Zaehler noch Nenner";
86
+ * `computeApplicable` ueberspringt eine Regel ohne Dimension bereits von selbst
87
+ * (`if (!dim) continue`). Sichtbar wird RC ueber die Ableitung `ALL_RULE_DEFS minus
88
+ * ausgewertet` beim Host: sechs Regeln, die als NICHT GEPRUEFT dastehen, solange kein Lauf
89
+ * `CodeFacts` mitbringt.
90
+ */
91
+ export declare const READINESS_SCORED_PROFILES: readonly ["se", "coding"];
70
92
  /**
71
93
  * Rule → dimension mapping. Some rules belong to multiple dimensions;
72
94
  * here we assign primary dimension per rule. R-01 appears in 'ver' (primary)
@@ -14,7 +14,7 @@ export const ReadinessDimension = z.enum([
14
14
  'arch', // Functional architecture (R-02, R-03, R-10, R-12)
15
15
  'alloc', // Module allocation (R-04)
16
16
  'ver', // Test coverage (R-01, R-05)
17
- 'schema', // Interface completeness (R-26 binding, SC-02/SC-04 usage)
17
+ 'schema', // Interface completeness (R-26 binding, SC-02 usage)
18
18
  'cr', // CR traceability (CR-R01..R03)
19
19
  'ms', // Milestone planning (MS-01..02)
20
20
  ]);
@@ -62,6 +62,28 @@ export const ReadinessReport = z.object({
62
62
  scores: z.array(ReadinessScore),
63
63
  timestamp: z.iso.datetime(),
64
64
  });
65
+ /**
66
+ * CR-SM-305 — welche Profile in die readiness-Zahlen eingehen, und warum `conformance` nicht.
67
+ *
68
+ * Der Nenner jeder Dimension ist `Σ (Elemente der Grundgesamtheit)` ueber die Regeln der
69
+ * Dimension (`readiness-compute.ts`). Eine Regel, die DEKLARIERT, aber nicht AUSGEWERTET wird,
70
+ * traegt damit zum Nenner bei und liefert null Verstoesse — der Score STEIGT, weil eine
71
+ * Pruefung nicht gelaufen ist. Dieselbe Fail-open-Klasse wie ND-01/02 vor CR-SM-286, nur an der
72
+ * Stelle, die am lautesten gelesen wird.
73
+ *
74
+ * Gemessen ueber vier Familien-Repos, was die sechs RC-Regeln in `arch`/`ver`/`schema`
75
+ * geschenkt haetten: graph-view-edit `schema` +5,0 Punkte (Nenner 24 → 40), graphify `arch`
76
+ * +2,1 und `ver` +1,8, alles Uebrige ≤ 0,2. Der Ausschlag sitzt genau dort, wo die Zahl am
77
+ * meisten wiegt — in der kleinen Dimension.
78
+ *
79
+ * Deshalb steht keine RC-ID in `RULE_TO_DIMENSION` oder `RULE_TO_PHASE`. Das ist keine Luecke,
80
+ * sondern die Aussage „nicht ausgewertet, also weder Zaehler noch Nenner";
81
+ * `computeApplicable` ueberspringt eine Regel ohne Dimension bereits von selbst
82
+ * (`if (!dim) continue`). Sichtbar wird RC ueber die Ableitung `ALL_RULE_DEFS minus
83
+ * ausgewertet` beim Host: sechs Regeln, die als NICHT GEPRUEFT dastehen, solange kein Lauf
84
+ * `CodeFacts` mitbringt.
85
+ */
86
+ export const READINESS_SCORED_PROFILES = ['se', 'coding'];
65
87
  /**
66
88
  * Rule → dimension mapping. Some rules belong to multiple dimensions;
67
89
  * here we assign primary dimension per rule. R-01 appears in 'ver' (primary)
@@ -79,8 +101,7 @@ export const RULE_TO_DIMENSION = {
79
101
  // CR-SM-231: R-29 (Testdatei-Exklusivitaet) gehoert zu 'ver' wie R-19 — beide bewerten die
80
102
  // Evidenz-Bindung einer Abnahme, R-19 ihre Praesenz, R-29 ihre Eindeutigkeit.
81
103
  'R-29': 'ver',
82
- 'R-22': 'alloc', 'R-23': 'alloc', 'R-26': 'schema', 'R-27': 'arch',
83
- // CR-GC-366: R-30 (Wirkketten-Bindung) und R-31 (io-Verdrahtung) bewerten beide, ob ein
104
+ 'R-22': 'alloc', 'R-23': 'alloc', 'R-26': 'schema', // CR-GC-366: R-30 (Wirkketten-Bindung) und R-31 (io-Verdrahtung) bewerten beide, ob ein
84
105
  // Funktionsblock ueberhaupt im Bauplan haengt — dieselbe Dimension wie R-20 (realRef).
85
106
  // NICHT 'uc': R-14..R-17 fragen, ob ein Behaelter gefuellt ist;
86
107
  // diese beiden fragen von der FUNC aus, ob sie angeschlossen ist.
@@ -88,19 +109,19 @@ export const RULE_TO_DIMENSION = {
88
109
  // uc
89
110
  'UC-01': 'uc', 'UC-02': 'uc', 'UC-03': 'uc', 'UC-04': 'uc',
90
111
  'UC-05': 'uc', 'UC-06': 'uc',
91
- 'R-14': 'uc', 'R-15': 'uc', 'R-16': 'uc', 'R-17': 'uc',
112
+ 'R-15': 'uc', 'R-16': 'uc', 'R-17': 'uc',
92
113
  // FC-04 (CR-SM-226): FCHAIN actor-bounded (trigger+consumer) — same dimension as FC-01..03.
93
- 'FC-01': 'uc', 'FC-02': 'uc', 'FC-03': 'uc', 'FC-04': 'uc',
114
+ 'FC-02': 'uc', 'FC-03': 'uc', 'FC-04': 'uc',
94
115
  // arch
95
- 'R-02': 'arch', 'R-03': 'arch', 'R-10': 'arch', 'R-12': 'arch',
116
+ 'R-02': 'arch', 'R-10': 'arch', 'R-12': 'arch',
96
117
  // alloc
97
118
  'R-04': 'alloc',
98
119
  // ver
99
120
  'R-01': 'ver', 'R-05': 'ver',
100
121
  // schema
101
122
  'SC-02': 'schema', // SC-01/SC-03 deleted (BOK-CR-026) — R-26 is the binding rule
102
- // CR-SM-226: SC-04 sharp per-FLOW SCHEMA-binding check same dimension as SC-02.
103
- 'SC-04': 'schema',
123
+ // SC-04 entfiel mit CR-SM-271: FLOW ohne SCHEMA ist jetzt Grammatik (R-18-Bein, error)
124
+ // und zaehlt damit unter R-18/'arch' statt als eigene 'schema'-Zeile.
104
125
  // structural rules without primary dimension → assigned by closest concern
105
126
  'R-08': 'arch',
106
127
  // near-duplicate detection
@@ -110,12 +131,12 @@ export const RULE_TO_DIMENSION = {
110
131
  // rule (CR-SM-223) — a per-module advisory would depress this score permanently.
111
132
  'MT-01': 'alloc', 'MT-02': 'alloc',
112
133
  // CR traceability
113
- 'CR-R01': 'cr', 'CR-R02': 'cr', 'CR-R03': 'cr', 'CR-R04': 'cr',
114
- // architecture optimization
115
- 'AO-D01': 'arch', 'AO-D03': 'arch',
134
+ 'CR-R01': 'cr', 'CR-R02': 'cr', 'CR-R03': 'cr', // architecture optimization
135
+ // CR-SM-283: BW-02 (Whitebox-Randbreite) ersetzt AO-D03 an dieser Stelle — dieselbe
136
+ // Dimension, denn beide fragen nach der Struktur des Funktionsschnitts, nicht nach Evidenz.
137
+ 'BW-02': 'arch',
116
138
  // allocation rules (CR-191)
117
- 'CR-01': 'arch', 'RT-01': 'arch', 'PH-01': 'arch', 'CA-01': 'arch',
118
- // milestone planning
139
+ 'CR-01': 'arch', // milestone planning
119
140
  'MS-01': 'ms', 'MS-02': 'ms', 'MS-03': 'ms',
120
141
  // FMEA / risk
121
142
  'FM-01': 'req', 'FM-02': 'req', 'FM-03': 'ver',
@@ -161,7 +182,7 @@ export const RULE_TO_PHASE = {
161
182
  'BQ-01': 'SRR', 'BQ-02': 'SRR', 'BQ-04': 'SRR', 'BQ-06': 'SRR', 'BQ-07': 'SRR',
162
183
  'RD-01': 'SRR', 'RD-02': 'SRR', 'RD-03': 'SRR',
163
184
  'UC-01': 'SRR', 'UC-02': 'SRR', 'UC-03': 'SRR', 'UC-04': 'SRR', 'UC-05': 'SRR', 'UC-06': 'SRR',
164
- 'R-14': 'SRR', 'R-16': 'SRR', 'R-17': 'SRR',
185
+ 'R-16': 'SRR', 'R-17': 'SRR',
165
186
  'FC-02': 'SRR',
166
187
  'CL-01': 'SRR',
167
188
  'FM-01': 'SRR', 'FM-02': 'SRR',
@@ -169,21 +190,18 @@ export const RULE_TO_PHASE = {
169
190
  'MS-01': 'SRR', 'MS-02': 'SRR', 'MS-03': 'SRR',
170
191
  // PDR — architecture/functional completeness.
171
192
  'RD-04': 'PDR',
172
- 'R-02': 'PDR', 'R-03': 'PDR', 'R-08': 'PDR', 'R-10': 'PDR', 'R-12': 'PDR', 'R-18': 'PDR',
193
+ 'R-02': 'PDR', 'R-08': 'PDR', 'R-10': 'PDR', 'R-12': 'PDR', 'R-18': 'PDR',
173
194
  'R-04': 'PDR', 'R-22': 'PDR', 'R-23': 'PDR',
174
195
  'R-15': 'PDR',
175
- 'FC-01': 'PDR', 'FC-03': 'PDR', 'FC-04': 'PDR',
196
+ 'FC-03': 'PDR', 'FC-04': 'PDR',
176
197
  // CR-GC-366: Anschluss des Funktionsbaus — gehoert an dasselbe Gate wie R-15/IO-01,
177
198
  // die auf derselben Kette aufsetzen.
178
199
  'R-30': 'PDR', 'R-31': 'PDR',
179
200
  'MT-01': 'PDR', 'MT-02': 'PDR',
180
201
  'ND-01': 'PDR',
181
- 'AO-D01': 'PDR', 'AO-D03': 'PDR', 'CR-01': 'PDR', 'RT-01': 'PDR', 'PH-01': 'PDR', 'CA-01': 'PDR',
182
- 'IO-01': 'PDR', // CR-SM-226: extended to all FCHAIN FUNC-pairs, added to the phase axis.
183
- 'CR-R04': 'PDR',
202
+ 'BW-02': 'PDR', 'CR-01': 'PDR', 'IO-01': 'PDR', // CR-SM-226: extended to all FCHAIN FUNC-pairs, added to the phase axis.
184
203
  // CDR — critical design/schema completeness.
185
- 'R-26': 'CDR', 'R-27': 'CDR',
186
- 'SC-02': 'CDR', 'SC-04': 'CDR', // SC-04: FLOW→SCHEMA sharp rule (CR-SM-226)
204
+ 'R-26': 'CDR', 'SC-02': 'CDR', // SC-04 entfiel mit CR-SM-271 — der FLOW-ohne-SCHEMA-Fall haengt an R-18/PDR
187
205
  'ND-02': 'CDR',
188
206
  'NFR-01': 'CDR',
189
207
  // TRR — test readiness.
@@ -0,0 +1,52 @@
1
+ /**
2
+ * rule-help.ts — die Regelhilfe liegt NEBEN der Regel (CR-SM-300).
3
+ *
4
+ * Ein Hilfeeintrag ist keine Annotation *ueber* einer Regel, er ist **Teil ihrer Lieferung**:
5
+ * eine Regel, deren Befund niemand lesen kann, ist nicht fertig. Bis hierher lag die Schicht in
6
+ * graphcode (CR-GC-227, bewusst, aus Tempo — dort brauchte sie keinen Bump und kein Review), und
7
+ * derselbe CR hat die Verschiebung ausdruecklich als spaetere Entscheidung notiert. Sie ist jetzt
8
+ * getroffen; der Grund ist die Drift, die sie erzeugt hat: 11 Eintraege zu geloeschten Regeln und
9
+ * 8 Katalogregeln ohne Eintrag, unbemerkt ueber vier Releases. Hinter einem Symlink gilt kein
10
+ * Versionsbereich (CR-GC-488 §1a) — eine Pruefung im ungelesenen Repo ist keine Pruefung.
11
+ *
12
+ * ## Was hier NICHT steht
13
+ *
14
+ * - **Abgeleitetes** — Titel, Severity, Meldung und `fix_hint` stehen an der Regeldefinition
15
+ * (`ALL_RULE_DEFS`), die Dimensions-/Phasenzuordnung in `readiness.ts`. Kein Wort davon wird
16
+ * hier wiederholt; ein zweiter Speicher derselben Wahrheit laeuft auseinander.
17
+ * - **`fix_hint` gegen `plain`/`se`** — `fix_hint` ist die Anweisung an den AGENTEN („Add a
18
+ * `verify` trace"), `plain`/`se` die Erklaerung fuer den MENSCHEN („was ist hier eigentlich
19
+ * kaputt, und wie heisst das in der SE-Literatur"). Verschiedene Leser, verschiedene Laenge,
20
+ * verschiedene Sprache — deshalb drei Felder und nicht eines.
21
+ * - **Nicht-Regel-Hilfe** — Dashboard-Panels, Artefakte, das Vokabular und die sechs
22
+ * Metrik-Dimensionen (`HELP_METRICS`, CR-GC-458) bleiben in graphcode: sie sind an dessen
23
+ * Oberflaeche gebunden, nicht an den Regelkatalog.
24
+ *
25
+ * ## Was die Version haelt
26
+ *
27
+ * **Die PRAESENZ ist Oberflaeche** und haengt an `RULES_VERSION`: eine Regel ohne Hilfeeintrag
28
+ * kann nicht landen, ein Eintrag ohne Regel auch nicht (`tests/unit/se-rule-help.test.ts`,
29
+ * beidseitig, gegen die lebenden Registraturen — nie gegen eine Handzaehlung).
30
+ * **Der TEXT ist es nicht.** „Prosa ist ein Patch-Bump, keine Grammatik" (CR-SM-244): ein
31
+ * umformulierter Satz darf keinen Major ausloesen, deshalb steht im Golden-File nur die
32
+ * Schluesselmenge, nicht die Prosa.
33
+ *
34
+ * Sprache: Englisch, wie die Regelbeschreibungen selbst. 18,6 KB reine Strings — der
35
+ * `./browser`-Eintrag bleibt transitiv `node:`-frei (CR-SM-230), Strings ziehen nichts nach.
36
+ *
37
+ * @author andreas@siglochconsulting
38
+ */
39
+ /** Ein verfasster Hilfeeintrag: die zwei Klartext-Schichten, dazu ein Kopier-Prompt, wo einer passt. */
40
+ export interface RuleHelpEntry {
41
+ /** Schicht 0 — ohne SE-Jargon; endet mit der EINEN einfachen Handlung. */
42
+ readonly plain: string;
43
+ /** Schicht 1 — uebersetzt unsere Kodierung in den Standardbegriff der Systems-Engineering-Literatur. */
44
+ readonly se: string;
45
+ /** Schicht 2 — ein kopierbarer Prompt (`se:*`-Skill oder MCP-Aufruf), wo einer passt. */
46
+ readonly prompt?: string;
47
+ }
48
+ /**
49
+ * Je Regel-ID der Hilfeeintrag — Katalogregeln (`ALL_RULE_DEFS`) UND Conformance-Regeln
50
+ * (`CODE_CONFORMANCE_RULES`). Vollstaendig in beide Richtungen, erzwungen im Test.
51
+ */
52
+ export declare const RULE_HELP: Record<string, RuleHelpEntry>;