@sigloch/contracts 6.3.0 → 10.0.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/dist/se/ao-rules.d.ts +12 -12
- package/dist/se/ao-rules.js +88 -225
- package/dist/se/conformance-rules.d.ts +28 -0
- package/dist/se/conformance-rules.js +40 -17
- package/dist/se/cr-quality-rules.js +75 -58
- package/dist/se/evaluate-all.d.ts +4 -2
- package/dist/se/evaluate-all.js +40 -24
- package/dist/se/fchain-quality-rules.d.ts +0 -1
- package/dist/se/fchain-quality-rules.js +0 -44
- package/dist/se/flat-graph.d.ts +9 -1
- package/dist/se/flat-graph.js +15 -6
- package/dist/se/format-e-parser.d.ts +14 -2
- package/dist/se/format-e-parser.js +33 -9
- package/dist/se/grammar-snapshot.d.ts +10 -7
- package/dist/se/grammar-snapshot.js +172 -27
- package/dist/se/index.d.ts +4 -3
- package/dist/se/index.js +4 -3
- package/dist/se/meta-model.d.ts +99 -7
- package/dist/se/meta-model.js +155 -14
- package/dist/se/metric-rules.d.ts +20 -1
- package/dist/se/metric-rules.js +97 -58
- package/dist/se/module-crossings.d.ts +102 -0
- package/dist/se/module-crossings.js +196 -0
- package/dist/se/near-duplicate-rules.d.ts +16 -24
- package/dist/se/near-duplicate-rules.js +21 -92
- package/dist/se/ontology.d.ts +32 -47
- package/dist/se/ontology.js +56 -13
- package/dist/se/policy.d.ts +6 -0
- package/dist/se/policy.js +53 -2
- package/dist/se/quality-rules.d.ts +18 -0
- package/dist/se/quality-rules.js +68 -12
- package/dist/se/readiness.d.ts +7 -5
- package/dist/se/readiness.js +40 -22
- package/dist/se/rules.d.ts +6 -7
- package/dist/se/rules.js +358 -128
- package/dist/se/schema-quality-rules.d.ts +0 -1
- package/dist/se/schema-quality-rules.js +7 -28
- package/dist/se/similarity.d.ts +61 -0
- package/dist/se/similarity.js +116 -0
- package/dist/se/uc-quality-rules.js +31 -12
- package/package.json +3 -2
|
@@ -1,16 +1,55 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
|
-
// CR-R01:
|
|
2
|
+
// CR-R01: ein offener CR nennt, WAS er aendert (CR-SM-295)
|
|
3
|
+
//
|
|
4
|
+
// Bis hierher waren es zwei Regeln, und beide zielten daneben. CR-R01 verlangte
|
|
5
|
+
// IRGENDEINE relation-Kante — und akzeptierte damit einen CR, der nur an einem
|
|
6
|
+
// Meilenstein haengt: das ist ein Termin, kein Umfang. Ueber 514 CR-Knoten in 19
|
|
7
|
+
// Familiengraphen feuerte sie 5-mal, waehrend 49 CRs ausschliesslich auf ein MS zeigten
|
|
8
|
+
// und unbeanstandet blieben. CR-R04 verlangte umgekehrt einen FUNC — zu eng: 21 CRs
|
|
9
|
+
// meldeten, und ein grosser Teil davon aendert Daten, Doku oder Konfiguration und
|
|
10
|
+
// beruehrt zu Recht keine Funktion.
|
|
11
|
+
//
|
|
12
|
+
// Die tragende Frage ist keine von beiden, sondern: nennt dieser CR ein Element, das er
|
|
13
|
+
// AENDERT? Umfang sind FUNC, MOD, SCHEMA, REQ und UC. MS ist Terminplanung und zaehlt
|
|
14
|
+
// nicht — MS-03 stellt diese Frage getrennt und bleibt unberuehrt.
|
|
15
|
+
//
|
|
16
|
+
// Grundgesamtheit wie bei CR-R04 (CR-SM-255) — nur was noch steuerbar ist. An einem
|
|
17
|
+
// geschlossenen CR ist die Frage Archaeologie: was er beruehrt hat, steht im Commit.
|
|
18
|
+
//
|
|
19
|
+
// Die Menge ist aber UMGEDREHT formuliert: nicht "open oder in-progress", sondern "nicht
|
|
20
|
+
// abgeschlossen". Der Grund ist gemessen — im Bestand tragen CRs die Status `done` (463),
|
|
21
|
+
// `open` (34), `planned` (12), `rejected` (2), `dropped` (1) und keinen (2). `planned`
|
|
22
|
+
// steht in keinem Enum der Ontologie, wird aber real geschrieben; eine Positivliste haette
|
|
23
|
+
// diese zwoelf CRs stillschweigend uebersprungen. Eine Regel, die durch einen ihr
|
|
24
|
+
// unbekannten Statuswert stumm wird, ist von einer bestandenen Pruefung nicht zu
|
|
25
|
+
// unterscheiden — dieselbe Fail-open-Klasse wie ND-01/ND-02 vor CR-SM-286.
|
|
26
|
+
//
|
|
27
|
+
// Ein CR ganz OHNE status ist erst recht nicht abgeschlossen.
|
|
28
|
+
//
|
|
29
|
+
// Gemessen vor der Umstellung: von 514 CRs tragen 54 keinen Umfangsbezug — davon sind
|
|
30
|
+
// **0 offen**, 52 `done` und 2 ohne Status. Die neue Fassung feuert am Bestand also auf
|
|
31
|
+
// hoechstens 2 und laesst die Historie unangetastet; ihre Wirkung beginnt beim naechsten
|
|
32
|
+
// CR, der geschrieben wird.
|
|
3
33
|
// ---------------------------------------------------------------------------
|
|
34
|
+
/** Elementtypen, die einen Aenderungsumfang darstellen — MS gehoert bewusst nicht dazu. */
|
|
35
|
+
const SCOPE_TYPES = new Set(['FUNC', 'MOD', 'SCHEMA', 'REQ', 'UC']);
|
|
36
|
+
/** Abgeschlossen heisst: nicht mehr steuerbar. Alles andere ist Grundgesamtheit. */
|
|
37
|
+
const CLOSED_STATUS = new Set(['done', 'dropped', 'rejected']);
|
|
4
38
|
function crMustTrack(graph) {
|
|
5
|
-
const
|
|
39
|
+
const typeOf = new Map(graph.elements.map(e => [e.id, e.type]));
|
|
40
|
+
const crs = graph.elements.filter(e => {
|
|
41
|
+
if (e.type !== 'CR')
|
|
42
|
+
return false;
|
|
43
|
+
return !CLOSED_STATUS.has(String(e.attributes?.status ?? ''));
|
|
44
|
+
});
|
|
6
45
|
return crs
|
|
7
|
-
.filter(cr => !graph.traces.some(t => t.source === cr.id && t.type === 'relation'))
|
|
46
|
+
.filter(cr => !graph.traces.some(t => t.source === cr.id && t.type === 'relation' && SCOPE_TYPES.has(typeOf.get(t.target) ?? '')))
|
|
8
47
|
.map(cr => ({
|
|
9
48
|
rule_id: 'CR-R01',
|
|
10
49
|
severity: 'error',
|
|
11
50
|
element_id: cr.id,
|
|
12
|
-
message: `${cr.id}
|
|
13
|
-
fix_hint: 'Add relation
|
|
51
|
+
message: `${cr.id} names no scope (no relation to FUNC/MOD/SCHEMA/REQ/UC)`,
|
|
52
|
+
fix_hint: 'Add a relation trace to the FUNC, MOD, SCHEMA, REQ or UC this CR changes — a milestone alone is a date, not a scope',
|
|
14
53
|
context: {
|
|
15
54
|
element_type: cr.type,
|
|
16
55
|
element_name: cr.name,
|
|
@@ -63,71 +102,50 @@ function noConcurrentMutation(graph) {
|
|
|
63
102
|
targetToCrs.set(tgt, list);
|
|
64
103
|
}
|
|
65
104
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
105
|
+
// CR-SM-304 — EIN Befund je Konflikt-MENGE, aber an einem BERECHENBAREN Element.
|
|
106
|
+
//
|
|
107
|
+
// Die Ein-Befund-Regel bleibt: dieselben zwei offenen CRs, die sich an drei Knoten begegnen,
|
|
108
|
+
// sind EIN Koordinationsproblem und nicht drei (Gate 4, Doppelzaehlung). Falsch war, woher der
|
|
109
|
+
// Anker kam: `targetToCrs` folgt der TRACE-Reihenfolge, also entschied die Array-Ordnung im
|
|
110
|
+
// Graphen, welches Ziel meldet — "kein erster Treffer" ist Gate 5 woertlich, und dieselbe
|
|
111
|
+
// Klasse wie der offene R-28-Fall (CR-SM-245). Gemessen am graphcode-Selbstmodell wechselte
|
|
112
|
+
// der Befund bei umgedrehter Reihenfolge von FUNC-graph-suggest auf MS-9-generation; ein
|
|
113
|
+
// Reseed aus dem Kuzu-Store reichte, damit eine Vorher/Nachher-Bilanz bei NULL Zuegen
|
|
114
|
+
// "einen geschlossen, einen neu" meldete.
|
|
115
|
+
//
|
|
116
|
+
// Zweiter Teil desselben Defekts: das unterdrueckte Ziel wurde nicht nur nicht angekert, es
|
|
117
|
+
// wurde gar nicht genannt. Wer koordinieren soll, braucht die vollstaendige Liste — sie steht
|
|
118
|
+
// jetzt in der Meldung und als `also_affects` im Kontext.
|
|
119
|
+
const bySet = new Map();
|
|
120
|
+
for (const target of [...targetToCrs.keys()].sort()) {
|
|
121
|
+
const crIds = [...targetToCrs.get(target)].sort();
|
|
69
122
|
if (crIds.length < 2)
|
|
70
123
|
continue;
|
|
71
|
-
const key = crIds.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
124
|
+
const key = crIds.join(',');
|
|
125
|
+
bySet.set(key, [...(bySet.get(key) ?? []), target]);
|
|
126
|
+
}
|
|
127
|
+
const violations = [];
|
|
128
|
+
for (const [key, targets] of bySet) {
|
|
129
|
+
const crIds = key.split(',');
|
|
130
|
+
const [anchor, ...also] = targets;
|
|
131
|
+
const el = graph.elements.find(e => e.id === anchor);
|
|
75
132
|
violations.push({
|
|
76
133
|
rule_id: 'CR-R03',
|
|
77
134
|
severity: 'warning',
|
|
78
|
-
element_id:
|
|
79
|
-
message: `${
|
|
135
|
+
element_id: anchor,
|
|
136
|
+
message: `${anchor} is tracked by ${crIds.length} open CRs: ${crIds.join(', ')}` +
|
|
137
|
+
(also.length > 0 ? ` — the same CRs also track ${also.join(', ')}` : ''),
|
|
80
138
|
fix_hint: 'Coordinate changes to avoid merge conflicts',
|
|
81
139
|
context: {
|
|
82
|
-
element_type:
|
|
83
|
-
element_name:
|
|
140
|
+
element_type: el?.type,
|
|
141
|
+
element_name: el?.name,
|
|
142
|
+
also_affects: also,
|
|
84
143
|
},
|
|
85
144
|
});
|
|
86
145
|
}
|
|
87
146
|
return violations;
|
|
88
147
|
}
|
|
89
148
|
// ---------------------------------------------------------------------------
|
|
90
|
-
// CR-R04: an OPEN CR must have at least one relation→FUNC trace (CR-207,
|
|
91
|
-
// Grundgesamtheit verengt in CR-SM-255)
|
|
92
|
-
//
|
|
93
|
-
// "Welche Funktionen fasst dieser CR an" ist eine PLANUNGSfrage — sie steuert, bevor
|
|
94
|
-
// gebaut wird. An einem geschlossenen CR ist sie Archaeologie: was er beruehrt hat,
|
|
95
|
-
// steht im Commit und im Diff, nicht im Graphen. Wer die Kanten nachtraeglich zieht,
|
|
96
|
-
// raet, und erfundene Praezision ist teurer als eine fehlende Kante.
|
|
97
|
-
//
|
|
98
|
-
// Gemessen am graphcode-Selbstmodell (graphVersion 171): 41 meldende CRs, davon 40
|
|
99
|
-
// `done` und 1 `dropped` — kein einziger offener. Die Regel feuerte ausschliesslich
|
|
100
|
-
// dort, wo sie nichts mehr steuern kann, und trug damit 41 unbearbeitbare Befunde.
|
|
101
|
-
//
|
|
102
|
-
// Die Statusmenge ist woertlich die von CR-R03 (s. o.): dieselbe Frage nach "noch in
|
|
103
|
-
// Arbeit", dieselbe Antwort. CR-R01 ("ein CR trackt ueberhaupt etwas") bleibt fuer
|
|
104
|
-
// ALLE CRs gueltig — nur die Verschaerfung "und zwar einen FUNC" ist Planung.
|
|
105
|
-
// ---------------------------------------------------------------------------
|
|
106
|
-
function crMustHaveFunc(graph) {
|
|
107
|
-
// Ein CR ganz OHNE status ist kein geschlossener CR — die Regel darf nicht durch ein
|
|
108
|
-
// fehlendes Attribut stumm werden.
|
|
109
|
-
const crs = graph.elements.filter(e => {
|
|
110
|
-
if (e.type !== 'CR')
|
|
111
|
-
return false;
|
|
112
|
-
const status = e.attributes?.status;
|
|
113
|
-
return status === undefined || status === 'open' || status === 'in-progress';
|
|
114
|
-
});
|
|
115
|
-
return crs
|
|
116
|
-
.filter(cr => !graph.traces.some(t => t.source === cr.id && t.type === 'relation' &&
|
|
117
|
-
graph.elements.some(e => e.id === t.target && e.type === 'FUNC')))
|
|
118
|
-
.map(cr => ({
|
|
119
|
-
rule_id: 'CR-R04',
|
|
120
|
-
severity: 'warning',
|
|
121
|
-
element_id: cr.id,
|
|
122
|
-
message: `${cr.id} has no relation→FUNC trace (no implementation scope)`,
|
|
123
|
-
fix_hint: 'Add CR→FUNC [relation] traces to define which functions this CR changes',
|
|
124
|
-
context: {
|
|
125
|
-
element_type: cr.type,
|
|
126
|
-
element_name: cr.name,
|
|
127
|
-
},
|
|
128
|
-
}));
|
|
129
|
-
}
|
|
130
|
-
// ---------------------------------------------------------------------------
|
|
131
149
|
// MS-03: CR should have a CR→MS [relation] trace (CR-207)
|
|
132
150
|
// ---------------------------------------------------------------------------
|
|
133
151
|
function crShouldHaveMilestone(graph) {
|
|
@@ -159,7 +177,6 @@ export const CR_RULES = [
|
|
|
159
177
|
// (= alle Elemente) ist die einzige Menge, aus der der Zielknoten garantiert stammt.
|
|
160
178
|
// Damit ist sie nach R-08/R-18 die dritte 'all'-Regel — bewusst, nicht vergessen.
|
|
161
179
|
{ id: 'CR-R03', name: 'No concurrent mutation', severity: 'warning', evaluate: noConcurrentMutation, domain: ['all'] },
|
|
162
|
-
{ id: 'CR-R04', name: 'Open CR must have FUNC', severity: 'warning', evaluate: crMustHaveFunc, domain: ['CR'] },
|
|
163
180
|
{ id: 'MS-03', name: 'CR without milestone', severity: 'info', evaluate: crShouldHaveMilestone, domain: ['CR'] },
|
|
164
181
|
];
|
|
165
182
|
// CR-SM-236: `policy` wird durchgereicht, auch wo diese Familie heute keine Schwelle hat —
|
|
@@ -13,14 +13,16 @@ import type { MetricPolicy } from './policy.js';
|
|
|
13
13
|
* hier statt eine eigene Tabelle zu fuehren. Eine zweite Tabelle kann nicht hinterherhinken,
|
|
14
14
|
* wenn es keine zweite gibt.
|
|
15
15
|
*/
|
|
16
|
+
/** Profile groupings — see CATALOGS. */
|
|
17
|
+
export type ProfileId = 'default' | 'se' | 'coding';
|
|
16
18
|
export declare const ALL_RULE_DEFS: ReadonlyArray<{
|
|
17
19
|
id: string;
|
|
18
20
|
name: string;
|
|
19
21
|
severity: 'error' | 'warning' | 'info';
|
|
20
22
|
domain: readonly string[];
|
|
23
|
+
/** CR-SM-285: das Profil reist mit der Regel, statt aus ihrer ID geraten zu werden. */
|
|
24
|
+
profile: Exclude<ProfileId, 'default'>;
|
|
21
25
|
}>;
|
|
22
|
-
/** Profile groupings derived from rule prefixes. */
|
|
23
|
-
export type ProfileId = 'default' | 'se' | 'coding';
|
|
24
26
|
export declare function getRuleDefsForProfile(profile: ProfileId): typeof ALL_RULE_DEFS;
|
|
25
27
|
/**
|
|
26
28
|
* Evaluate all rules against a graph. Single call replaces the individual evaluator calls.
|
package/dist/se/evaluate-all.js
CHANGED
|
@@ -3,6 +3,7 @@ import { SC_RULES, evaluateSCRules } from './schema-quality-rules.js';
|
|
|
3
3
|
import { UC_RULES, evaluateUCRules } from './uc-quality-rules.js';
|
|
4
4
|
import { FC_RULES, evaluateFCRules } from './fchain-quality-rules.js';
|
|
5
5
|
import { MT_RULES, evaluateMTRules } from './metric-rules.js';
|
|
6
|
+
import { toEvaluableGraph } from './flat-graph.js';
|
|
6
7
|
import { FM_RULES, evaluateFMRules } from './fmea-rules.js';
|
|
7
8
|
import { VIEW_RULES, evaluateViewRules } from './view-rules.js';
|
|
8
9
|
import { CR_RULES, evaluateCRRules } from './cr-quality-rules.js';
|
|
@@ -11,33 +12,38 @@ import { AO_RULES, evaluateAORules } from './ao-rules.js';
|
|
|
11
12
|
import { BQ_RULES, evaluateBQRules } from './quality-rules.js';
|
|
12
13
|
import { AF_RULES, evaluateAFRules } from './analysis-freshness-rules.js';
|
|
13
14
|
/**
|
|
14
|
-
*
|
|
15
|
+
* CR-SM-285: das Profil haengt am KATALOG, nicht am ID-Praefix.
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* Bis hierher ordnete `SE_PREFIXES`/`CODING_PREFIXES` eine Regel ueber den Anfang ihrer ID zu.
|
|
18
|
+
* Drei dokumentierte Ausfaelle derselben Klasse: `RD-` (CR-SM-221 — `'RD-01'.startsWith('R-')`
|
|
19
|
+
* ist false, die Zerlegungsregeln liefen nie im se-Profil), `MS-` (CR-SM-245 — fehlte in BEIDEN
|
|
20
|
+
* Listen, die Dimension `ms` hatte im se-Profil keine einzige zaehlende Regel), `BW-`
|
|
21
|
+
* (CR-SM-283). Jede neue Regel-ID war ein potenzieller vierter.
|
|
22
|
+
*
|
|
23
|
+
* Ein Katalog weiss, wozu er gehoert; eine Zeichenkette weiss es nicht. Neue Regeln erben das
|
|
24
|
+
* Profil ihres Katalogs automatisch — und ein NEUER Katalog muss hier eingetragen werden, sonst
|
|
25
|
+
* bricht `ALL_RULE_DEFS` schon beim Typcheck (jeder Eintrag braucht sein Profil).
|
|
20
26
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
const CATALOGS = [
|
|
28
|
+
{ profile: 'se', rules: V3_RULES },
|
|
29
|
+
{ profile: 'se', rules: UC_RULES },
|
|
30
|
+
{ profile: 'se', rules: FC_RULES },
|
|
31
|
+
{ profile: 'se', rules: SC_RULES },
|
|
32
|
+
{ profile: 'se', rules: MT_RULES },
|
|
33
|
+
{ profile: 'se', rules: CR_RULES },
|
|
34
|
+
{ profile: 'se', rules: AO_RULES },
|
|
35
|
+
{ profile: 'se', rules: FM_RULES },
|
|
36
|
+
{ profile: 'se', rules: VIEW_RULES },
|
|
37
|
+
{ profile: 'se', rules: AF_RULES },
|
|
38
|
+
// Sprach-/Textqualitaet statt SE-Struktur — das ist die Trennlinie, die die Praefixliste meinte.
|
|
39
|
+
{ profile: 'coding', rules: BQ_RULES },
|
|
40
|
+
{ profile: 'coding', rules: ND_RULES },
|
|
41
|
+
];
|
|
42
|
+
export const ALL_RULE_DEFS = CATALOGS.flatMap(({ profile, rules }) => rules.map(r => ({ id: r.id, name: r.name, severity: r.severity, domain: r.domain, profile })));
|
|
35
43
|
export function getRuleDefsForProfile(profile) {
|
|
36
|
-
if (profile === '
|
|
37
|
-
return ALL_RULE_DEFS
|
|
38
|
-
|
|
39
|
-
return ALL_RULE_DEFS.filter(r => CODING_PREFIXES.some(p => r.id.startsWith(p)));
|
|
40
|
-
return ALL_RULE_DEFS;
|
|
44
|
+
if (profile === 'default')
|
|
45
|
+
return ALL_RULE_DEFS;
|
|
46
|
+
return ALL_RULE_DEFS.filter(r => r.profile === profile);
|
|
41
47
|
}
|
|
42
48
|
/**
|
|
43
49
|
* Evaluate all rules against a graph. Single call replaces the individual evaluator calls.
|
|
@@ -47,6 +53,16 @@ export function getRuleDefsForProfile(profile) {
|
|
|
47
53
|
* `DEFAULT_METRIC_POLICY` sichtbar an der Aufrufstelle.
|
|
48
54
|
*/
|
|
49
55
|
export function evaluateAllRules(graph, policy) {
|
|
56
|
+
// CR-SM-284: die Hebung der flach committeten SSOT laeuft HIER, nicht beim Aufrufer.
|
|
57
|
+
//
|
|
58
|
+
// `toEvaluableGraph` gibt es seit CR-SM-258 — und sie wurde von keinem Produktionspfad und
|
|
59
|
+
// keinem Messskript gerufen, nur aus Tests. Eine Korrektur, die man rufen DARF statt MUSS, ist
|
|
60
|
+
// keine: an graphcode erzeugte die flache Lesart 158 Phantom-Befunde (R-19 124, R-20 115,
|
|
61
|
+
// R-26 36, CR-R04 42) und verdeckte zugleich 156 ECHTE Fehler (CR-R02, severity error).
|
|
62
|
+
//
|
|
63
|
+
// Idempotent und identitaetserhaltend (s. dort), also eine Normalisierung am einzigen Eingang
|
|
64
|
+
// und kein Fallback: ein bereits genesteter Graph geht unveraendert und uneingepackt durch.
|
|
65
|
+
graph = toEvaluableGraph(graph);
|
|
50
66
|
return [
|
|
51
67
|
...evaluateRules(graph, policy),
|
|
52
68
|
...evaluateBQRules(graph, policy),
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import type { OntologyGraph } from './ontology.js';
|
|
5
5
|
import type { RuleDefinition, RuleViolation } from './rules.js';
|
|
6
6
|
import type { MetricPolicy } from './policy.js';
|
|
7
|
-
export declare function fc01ActorBoundary(graph: OntologyGraph): RuleViolation[];
|
|
8
7
|
export declare function fc02LeafUcHasFchain(graph: OntologyGraph): RuleViolation[];
|
|
9
8
|
export declare function fc03FchainFlat(graph: OntologyGraph): RuleViolation[];
|
|
10
9
|
export declare function fc04ActorBounded(graph: OntologyGraph): RuleViolation[];
|
|
@@ -1,48 +1,5 @@
|
|
|
1
1
|
import { indexOf } from './graph-index.js';
|
|
2
2
|
// ---------------------------------------------------------------------------
|
|
3
|
-
// FC-01: FCHAIN must have Actor boundary (input or output via FLOW→ACTOR io)
|
|
4
|
-
// ---------------------------------------------------------------------------
|
|
5
|
-
export function fc01ActorBoundary(graph) {
|
|
6
|
-
// CR-SM-264: dieselbe Frage, einmal statt je Kette neu.
|
|
7
|
-
//
|
|
8
|
-
// Die alte Fassung war die verschachtelte Form, die UC-02 kubisch gemacht hat (CR-SM-261):
|
|
9
|
-
// je FCHAIN alle Traces, darin je io-Kante noch einmal alle Traces, darin je Treffer alle
|
|
10
|
-
// Elemente — `FCHAIN x FUNC x T x T x E`. Im Profil nach Teil a war FC-01 mit 6,3 % die
|
|
11
|
-
// teuerste FCHAIN-Regel.
|
|
12
|
-
//
|
|
13
|
-
// Beide Zweige fragen in Wahrheit DASSELBE: "beruehrt dieses Element eine io-Kante, deren
|
|
14
|
-
// anderes Ende ein ACTOR ist?" Einmal fuer den Zwischenknoten der Kettenglieder, einmal
|
|
15
|
-
// direkt fuer den Eltern-UC. Eine Menge beantwortet beide.
|
|
16
|
-
const idx = indexOf(graph);
|
|
17
|
-
const actorAdjacent = new Set();
|
|
18
|
-
for (const t of idx.tracesOfType('io')) {
|
|
19
|
-
if (idx.typeOf(t.target) === 'ACTOR')
|
|
20
|
-
actorAdjacent.add(t.source);
|
|
21
|
-
if (idx.typeOf(t.source) === 'ACTOR')
|
|
22
|
-
actorAdjacent.add(t.target);
|
|
23
|
-
}
|
|
24
|
-
return idx.elementsOfType('FCHAIN')
|
|
25
|
-
.filter(fc => {
|
|
26
|
-
// Mitglieder der Kette — bewusst OHNE Typfilter, wie in der alten Fassung: FC-01 fragt
|
|
27
|
-
// nach dem, was komponiert ist, nicht nach dem, was eine FUNC ist (FC-03 tut das).
|
|
28
|
-
const memberIds = idx.out(fc.id, 'compose').map(t => t.target);
|
|
29
|
-
const hasActorIO = memberIds.some(fid => idx.out(fid, 'io').some(t => actorAdjacent.has(t.target)) ||
|
|
30
|
-
idx.in(fid, 'io').some(t => actorAdjacent.has(t.source)));
|
|
31
|
-
// Der Umweg ueber den Eltern-UC: dessen eigene ACTOR-io zaehlt auch.
|
|
32
|
-
const parentUC = idx.in(fc.id, 'compose').find(t => idx.typeOf(t.source) === 'UC');
|
|
33
|
-
const hasDirectActorIO = parentUC !== undefined && actorAdjacent.has(parentUC.source);
|
|
34
|
-
return !hasActorIO && !hasDirectActorIO;
|
|
35
|
-
})
|
|
36
|
-
.map(fc => ({
|
|
37
|
-
rule_id: 'FC-01',
|
|
38
|
-
severity: 'warning',
|
|
39
|
-
element_id: fc.id,
|
|
40
|
-
message: `${fc.id} has no actor boundary (no ACTOR io connection)`,
|
|
41
|
-
fix_hint: 'Ensure at least one FUNC in the chain connects to an ACTOR via FLOW io',
|
|
42
|
-
context: { element_type: fc.type, element_name: fc.name },
|
|
43
|
-
}));
|
|
44
|
-
}
|
|
45
|
-
// ---------------------------------------------------------------------------
|
|
46
3
|
// FC-02: Leaf UC (no UC→compose→UC) must have at least one FCHAIN
|
|
47
4
|
// ---------------------------------------------------------------------------
|
|
48
5
|
export function fc02LeafUcHasFchain(graph) {
|
|
@@ -142,7 +99,6 @@ export function fc04ActorBounded(graph) {
|
|
|
142
99
|
// Aggregated
|
|
143
100
|
// ---------------------------------------------------------------------------
|
|
144
101
|
export const FC_RULES = [
|
|
145
|
-
{ id: 'FC-01', name: 'FCHAIN has actor boundary', severity: 'warning', evaluate: fc01ActorBoundary, domain: ['FCHAIN'] },
|
|
146
102
|
{ id: 'FC-02', name: 'Leaf UC has FCHAIN', severity: 'warning', evaluate: fc02LeafUcHasFchain, domain: ['UC'] },
|
|
147
103
|
// CR-SM-243: domain ist FUNC, nicht FCHAIN — die Regel meldet am FUNC mit der
|
|
148
104
|
// verschachtelten Zerlegung. Die FCHAIN ist der Suchraum, nicht die Grundgesamtheit:
|
package/dist/se/flat-graph.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
import type { OntologyGraph } from './ontology.js';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Hebt eine flach committete SSOT in die Form, die der Live-Gate dem Evaluator gibt.
|
|
4
|
+
*
|
|
5
|
+
* CR-SM-284: **identitaetserhaltend.** War nichts zu heben — der Normalfall, weil der Live-Gate
|
|
6
|
+
* bereits genestet liefert —, kommt DIESELBE Referenz zurueck. Das ist die Voraussetzung dafuer,
|
|
7
|
+
* dass `evaluateAllRules` die Funktion selbst rufen kann: die WeakMap-Caches der Familie
|
|
8
|
+
* (`indexOf`, `moduleCrossings`, `MEASURE_CACHE`) haengen an der Graph-Identitaet, und ein bei
|
|
9
|
+
* jedem Aufruf neu gebautes Objekt haette sie im Best-of-N-Loop bei jedem Kandidaten gesprengt.
|
|
10
|
+
*/
|
|
3
11
|
export declare function toEvaluableGraph(graph: OntologyGraph): OntologyGraph;
|
package/dist/se/flat-graph.js
CHANGED
|
@@ -42,11 +42,20 @@ function nestAttributes(entry, canonical) {
|
|
|
42
42
|
attributes.status = entry.status;
|
|
43
43
|
return { ...top, attributes };
|
|
44
44
|
}
|
|
45
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* Hebt eine flach committete SSOT in die Form, die der Live-Gate dem Evaluator gibt.
|
|
47
|
+
*
|
|
48
|
+
* CR-SM-284: **identitaetserhaltend.** War nichts zu heben — der Normalfall, weil der Live-Gate
|
|
49
|
+
* bereits genestet liefert —, kommt DIESELBE Referenz zurueck. Das ist die Voraussetzung dafuer,
|
|
50
|
+
* dass `evaluateAllRules` die Funktion selbst rufen kann: die WeakMap-Caches der Familie
|
|
51
|
+
* (`indexOf`, `moduleCrossings`, `MEASURE_CACHE`) haengen an der Graph-Identitaet, und ein bei
|
|
52
|
+
* jedem Aufruf neu gebautes Objekt haette sie im Best-of-N-Loop bei jedem Kandidaten gesprengt.
|
|
53
|
+
*/
|
|
46
54
|
export function toEvaluableGraph(graph) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
const elements = graph.elements.map((e) => nestAttributes(e, TOP_LEVEL_ELEMENT_KEYS));
|
|
56
|
+
const traces = graph.traces.map((t) => nestAttributes(t, TOP_LEVEL_TRACE_KEYS));
|
|
57
|
+
// `nestAttributes` gibt bei bereits genesteten Eintraegen das Original zurueck; sind ALLE
|
|
58
|
+
// unveraendert, war der Graph schon evaluierbar und wird nicht angefasst.
|
|
59
|
+
const untouched = elements.every((e, i) => e === graph.elements[i]) && traces.every((t, i) => t === graph.traces[i]);
|
|
60
|
+
return untouched ? graph : { ...graph, elements, traces };
|
|
52
61
|
}
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
*
|
|
10
10
|
* @sigloch/contracts/se
|
|
11
11
|
*/
|
|
12
|
-
import { ElementType } from './ontology.js';
|
|
13
|
-
import type {
|
|
12
|
+
import { ElementType, TraceType } from './ontology.js';
|
|
13
|
+
import type { OntologyGraph, AttributeSpec, ReqKind } from './ontology.js';
|
|
14
14
|
export interface FormatEOperation {
|
|
15
15
|
type: 'add_node' | 'remove_node' | 'update_node' | 'add_edge' | 'remove_edge' | 'strict_add_node' | 'strict_add_edge';
|
|
16
16
|
semanticId: string;
|
|
@@ -68,6 +68,18 @@ export interface ParseFormatEOptions {
|
|
|
68
68
|
* silent skip.
|
|
69
69
|
*/
|
|
70
70
|
resolveType?: (uid: string) => ElementType | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* CR-SM-266 B: die Kinds eines uid, den dieser Text nicht deklariert. Seit die
|
|
73
|
+
* satisfy-Patterns ein `where` tragen, entscheidet nicht mehr das Typ-Paar allein — ein
|
|
74
|
+
* `MOD -satisfy-> REQ` ist nur gueltig, wenn das REQ strukturelle Kinds traegt.
|
|
75
|
+
*
|
|
76
|
+
* Ohne diesen Resolver sieht der Parser die Kinds eines BESTEHENDEN Knotens nicht und lehnt
|
|
77
|
+
* solche Kanten ab. Das ist Absicht: fehlschlagen und es sagen, nicht raten und durchlassen
|
|
78
|
+
* — dieselbe Entscheidung wie bei `resolveType` ("Without it such a diff is an error, never
|
|
79
|
+
* a silent skip"). Knoten, die DIESER Text anlegt, brauchen ihn nicht; ihre Kinds stehen als
|
|
80
|
+
* `@kinds` in denselben Zeilen.
|
|
81
|
+
*/
|
|
82
|
+
resolveKinds?: (uid: string) => readonly ReqKind[] | undefined;
|
|
71
83
|
}
|
|
72
84
|
/** Parse a Format E text block into validated operations. */
|
|
73
85
|
export declare function parseFormatE(input: string, options?: ParseFormatEOptions): FormatEDiff;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* @sigloch/contracts/se
|
|
11
11
|
*/
|
|
12
|
-
import { ElementType, ELEMENT_ATTRIBUTES } from './ontology.js';
|
|
12
|
+
import { ElementType, ELEMENT_ATTRIBUTES, TraceType } from './ontology.js';
|
|
13
13
|
import { isValidTrace } from './meta-model.js';
|
|
14
14
|
// ---------------------------------------------------------------------------
|
|
15
15
|
// Extraction
|
|
@@ -23,9 +23,10 @@ export function extractFormatE(llmOutput) {
|
|
|
23
23
|
// ---------------------------------------------------------------------------
|
|
24
24
|
// Parser
|
|
25
25
|
// ---------------------------------------------------------------------------
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
// CR-SM-266 D5: ABGELEITET statt abgeschrieben. Die Liste stand hier als zweite Kopie des
|
|
27
|
+
// TraceType-Enums und trug `produces` noch, als es dort schon entfernt war — genau die Drift,
|
|
28
|
+
// die eine doppelte Wahrheit erzeugt. Eine Quelle, keine Pflege.
|
|
29
|
+
const VALID_TRACE_TYPES = new Set(TraceType.options);
|
|
29
30
|
const OP_PREFIX = {
|
|
30
31
|
'+': 'add',
|
|
31
32
|
'-': 'remove',
|
|
@@ -109,6 +110,24 @@ export function parseFormatE(input, options = {}) {
|
|
|
109
110
|
/** uid → type, from this text's node sections. */
|
|
110
111
|
const declared = new Map();
|
|
111
112
|
const typeOf = (uid) => declared.get(uid) ?? options.resolveType?.(uid);
|
|
113
|
+
/**
|
|
114
|
+
* CR-SM-266 B: die Kinds eines uid — erst aus DIESEM Text, dann aus dem Store.
|
|
115
|
+
*
|
|
116
|
+
* `kinds` reist in Format E als `@kinds a,b` und wird erst vom Konsumenten aufs
|
|
117
|
+
* Top-Level-Feld gehoben (graph-api-core, CR-195d). Hier steht es also noch in
|
|
118
|
+
* `op.attributes.kinds`, und genau dort wird es gelesen — sonst saehe eine Mutation, die
|
|
119
|
+
* REQ und satisfy-Kante in EINEM Block anlegt, die eigenen Kinds nicht.
|
|
120
|
+
*/
|
|
121
|
+
const kindsOf = (uid) => {
|
|
122
|
+
for (const op of operations) {
|
|
123
|
+
if ('elementType' in op && op.semanticId === uid && op.attributes?.kinds != null) {
|
|
124
|
+
const raw = op.attributes.kinds;
|
|
125
|
+
const list = Array.isArray(raw) ? raw.map(String) : String(raw).split(',');
|
|
126
|
+
return list.map(k => k.trim()).filter(Boolean);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return options.resolveKinds?.(uid);
|
|
130
|
+
};
|
|
112
131
|
for (const rawLine of input.split('\n')) {
|
|
113
132
|
const line = rawLine.trim();
|
|
114
133
|
if (!line || line.startsWith('//') || line.startsWith('#!'))
|
|
@@ -163,7 +182,7 @@ export function parseFormatE(input, options = {}) {
|
|
|
163
182
|
if (isEdgeLine || section === 'edges') {
|
|
164
183
|
const edgeMatch = isEdgeLine ? EDGE_RE.exec(line) : null;
|
|
165
184
|
if (edgeMatch) {
|
|
166
|
-
parseEdge(edgeMatch, typeOf, operations, errors);
|
|
185
|
+
parseEdge(edgeMatch, typeOf, kindsOf, operations, errors);
|
|
167
186
|
}
|
|
168
187
|
else {
|
|
169
188
|
errors.push(`Invalid edge line: "${line}"`);
|
|
@@ -223,7 +242,7 @@ function parseNode(m, elementType, ops, errors) {
|
|
|
223
242
|
ops.push({ type: 'add_node', semanticId: id, elementType, description: descr });
|
|
224
243
|
}
|
|
225
244
|
}
|
|
226
|
-
function parseEdge(m, typeOf, ops, errors) {
|
|
245
|
+
function parseEdge(m, typeOf, kindsOf, ops, errors) {
|
|
227
246
|
const opChar = m[1] || '+';
|
|
228
247
|
const sourceId = m[2];
|
|
229
248
|
const traceType = m[3];
|
|
@@ -254,7 +273,10 @@ function parseEdge(m, typeOf, ops, errors) {
|
|
|
254
273
|
}
|
|
255
274
|
// CR-148: Normalize before the meta-model check (e.g. FLOW→SCHEMA io → relation)
|
|
256
275
|
const resolvedTraceType = normalizeTraceType(srcType, tgtType, traceType);
|
|
257
|
-
if (!isValidTrace({
|
|
276
|
+
if (!isValidTrace({
|
|
277
|
+
source: srcType, target: tgtType, type: resolvedTraceType,
|
|
278
|
+
sourceKinds: kindsOf(sourceId), targetKinds: kindsOf(targetId),
|
|
279
|
+
})) {
|
|
258
280
|
errors.push(`Meta-model violation: ${srcType} -${traceType}-> ${tgtType} is not valid`);
|
|
259
281
|
continue;
|
|
260
282
|
}
|
|
@@ -281,7 +303,8 @@ function parseEdge(m, typeOf, ops, errors) {
|
|
|
281
303
|
export function serializeToFormatE(graph) {
|
|
282
304
|
const lines = [];
|
|
283
305
|
// Nodes, grouped by type
|
|
284
|
-
|
|
306
|
+
// CR-SM-266 D5: kein SESSION-Skip mehr — der Elementtyp existiert nicht.
|
|
307
|
+
const modelingElements = graph.elements;
|
|
285
308
|
if (modelingElements.length > 0) {
|
|
286
309
|
lines.push('## Nodes');
|
|
287
310
|
const byType = new Map();
|
|
@@ -313,7 +336,8 @@ export function serializeToFormatE(graph) {
|
|
|
313
336
|
}
|
|
314
337
|
}
|
|
315
338
|
// Edges
|
|
316
|
-
|
|
339
|
+
// CR-SM-266 D5: kein audit-Filter mehr — `Trace.category` existiert nicht.
|
|
340
|
+
const modelingTraces = graph.traces;
|
|
317
341
|
if (modelingTraces.length > 0) {
|
|
318
342
|
lines.push('');
|
|
319
343
|
lines.push('## Edges');
|
|
@@ -11,14 +11,17 @@
|
|
|
11
11
|
*/
|
|
12
12
|
export declare const GRAMMAR_SNAPSHOT: {
|
|
13
13
|
readonly versions: {
|
|
14
|
-
readonly ontology: "
|
|
15
|
-
readonly metaModel: "
|
|
16
|
-
readonly rules: "
|
|
14
|
+
readonly ontology: "9.0.0";
|
|
15
|
+
readonly metaModel: "5.0.0";
|
|
16
|
+
readonly rules: "19.0.0";
|
|
17
17
|
};
|
|
18
|
-
readonly elementTypes: readonly ["ACTOR", "CR", "FCHAIN", "FLOW", "FUNC", "MOD", "MS", "REQ", "SCHEMA", "
|
|
19
|
-
readonly traceTypes: readonly ["allocate", "compose", "io", "
|
|
20
|
-
readonly patterns: readonly ["ACTOR -io-> FLOW", "
|
|
18
|
+
readonly elementTypes: readonly ["ACTOR", "CR", "FCHAIN", "FLOW", "FUNC", "MOD", "MS", "REQ", "SCHEMA", "SYS", "TEST", "UC"];
|
|
19
|
+
readonly traceTypes: readonly ["allocate", "compose", "io", "relation", "satisfy", "verify"];
|
|
20
|
+
readonly patterns: readonly ["ACTOR -io-> FLOW", "CR -relation-> FUNC", "CR -relation-> MOD", "CR -relation-> MS", "CR -relation-> REQ", "CR -relation-> UC", "FCHAIN -compose-> FUNC [1..*]", "FCHAIN -satisfy-> REQ", "FLOW -io-> ACTOR", "FLOW -io-> FUNC", "FLOW -relation-> SCHEMA [1]", "FUNC -allocate-> MOD [0..1]", "FUNC -compose-> FUNC [0..*]", "FUNC -io-> FLOW", "FUNC -satisfy-> REQ where target.kinds in {functional,postcondition,precondition}", "MOD -compose-> MOD [0..*]", "MOD -satisfy-> REQ where target.kinds in {mitigation,non-functional,risk}", "MS -compose-> FUNC", "MS -compose-> REQ", "MS -compose-> UC", "MS -relation-> MS label=depends-on", "REQ -compose-> REQ [0..*]", "SYS -compose-> MOD [0..*]", "SYS -compose-> REQ [0..*]", "SYS -compose-> SYS [0..*]", "SYS -compose-> UC [1..*]", "SYS -satisfy-> REQ where target.kinds in {mitigation,non-functional,risk}", "TEST -verify-> REQ", "UC -compose-> FCHAIN [1..*]", "UC -compose-> REQ [1..*]"];
|
|
21
|
+
readonly elementColumns: readonly ["OntologyElement.attributes", "OntologyElement.created_at", "OntologyElement.description", "OntologyElement.id", "OntologyElement.kinds", "OntologyElement.method", "OntologyElement.name", "OntologyElement.status", "OntologyElement.type", "OntologyElement.updated_at", "Trace.attributes", "Trace.created_at", "Trace.label", "Trace.source", "Trace.target", "Trace.type", "Trace.verified_at", "Trace.weight"];
|
|
21
22
|
readonly attributes: readonly ["CR.rationale: string", "CR.spike: boolean", "CR.status: enum", "FLOW.protocol: string", "FLOW.qos: string", "FUNC.concept: boolean", "FUNC.external: boolean", "FUNC.measuredMs: number", "FUNC.realRef: object", "FUNC.safety_relevant: boolean", "FUNC.sourceFile: string", "FUNC.timingBudgetMs: number", "MOD.concept: boolean", "MOD.external: boolean", "MOD.kind: string", "MOD.path: string", "MOD.realRef: object", "REQ.detection: number", "REQ.occurrence: number", "REQ.severity: number", "SCHEMA.concept: boolean", "SCHEMA.contract: string", "SCHEMA.external: boolean", "SCHEMA.realRef: object", "TEST.concept: boolean", "TEST.sourceFile: string", "TEST.testRefs: array", "UC.operatingMode: string"];
|
|
22
|
-
readonly rules: readonly ["AF-01 (warning) domain=[graph]", "AF-02 (warning) domain=[graph]", "AF-03 (warning) domain=[graph]", "AF-04 (warning) domain=[graph]", "AF-05 (warning) domain=[graph]", "
|
|
23
|
+
readonly rules: readonly ["AF-01 (warning) domain=[graph]", "AF-02 (warning) domain=[graph]", "AF-03 (warning) domain=[graph]", "AF-04 (warning) domain=[graph]", "AF-05 (warning) domain=[graph]", "BQ-01 (warning) domain=[REQ]", "BQ-02 (warning) domain=[REQ]", "BQ-04 (warning) domain=[REQ]", "BQ-06 (warning) domain=[REQ]", "BQ-07 (warning) domain=[REQ]", "BW-02 (warning) domain=[FUNC]", "CL-01 (warning) domain=[ACTOR]", "CR-01 (warning) domain=[MOD]", "CR-R01 (error) domain=[CR]", "CR-R02 (error) domain=[CR]", "CR-R03 (warning) domain=[all]", "FC-02 (warning) domain=[UC]", "FC-03 (warning) domain=[FUNC]", "FC-04 (warning) domain=[FCHAIN]", "FM-01 (warning) domain=[REQ]", "FM-02 (warning) domain=[REQ]", "FM-03 (error) domain=[REQ]", "IO-01 (warning) domain=[FUNC]", "MS-01 (warning) domain=[MS]", "MS-02 (error) domain=[MS]", "MS-03 (info) domain=[CR]", "MT-01 (warning) domain=[MOD]", "MT-02 (info) domain=[MOD]", "ND-01 (error) domain=[FUNC]", "ND-02 (error) domain=[SCHEMA]", "NFR-01 (warning) domain=[FCHAIN,FUNC,MOD]", "R-01 (error) domain=[REQ]", "R-02 (warning) domain=[FUNC]", "R-04 (warning) domain=[MOD]", "R-05 (warning) domain=[TEST]", "R-08 (error) domain=[all]", "R-10 (warning) domain=[FLOW]", "R-12 (warning) domain=[FUNC]", "R-15 (warning) domain=[FCHAIN]", "R-16 (warning) domain=[ACTOR]", "R-17 (warning) domain=[SYS]", "R-18 (error) domain=[all]", "R-19 (warning) domain=[TEST]", "R-20 (warning) domain=[FUNC]", "R-21 (warning) domain=[FCHAIN]", "R-22 (warning) domain=[FUNC]", "R-23 (warning) domain=[MOD]", "R-26 (warning) domain=[SCHEMA]", "R-29 (error) domain=[TEST]", "R-30 (warning) domain=[FUNC]", "R-31 (warning) domain=[FUNC]", "RD-01 (warning) domain=[REQ]", "RD-02 (warning) domain=[REQ]", "RD-03 (info) domain=[REQ]", "RD-04 (warning) domain=[FUNC,MOD,SYS]", "SC-02 (warning) domain=[SCHEMA]", "UC-01 (error) domain=[UC]", "UC-02 (error) domain=[UC]", "UC-03 (warning) domain=[UC]", "UC-04 (warning) domain=[UC]", "UC-05 (info) domain=[UC]", "UC-06 (info) domain=[UC]", "VR-01 (info) domain=[TEST]"];
|
|
23
24
|
readonly conformanceRules: readonly ["RC-01 (error)", "RC-02 (error)", "RC-03 (error)", "RC-04 (warning)", "RC-05 (warning)", "RC-06 (warning)"];
|
|
25
|
+
readonly policy: readonly ["apTable = null", "boundaryWidth = {warning:5}", "crossingFlows = {warning:3}", "decompositionBreadth = {warning:9}", "instability = null", "lcom4 = {info:4,warning:6}", "moduleSize = {coupled:7,crossings:2,large:9}", "riskRpn = 100"];
|
|
26
|
+
readonly exports: readonly ["AF_RULES", "ALL_RULE_DEFS", "AO_RULES", "ActionPriority", "AnalysisArtifactId", "AnalysisFreshnessStampSchema", "ApTableSchema", "BOUNDED_PATTERNS", "BQ_RULES", "CODE_CONFORMANCE_RULES", "CR_RULES", "CodeFactsSchema", "DEFAULT_METRIC_POLICY", "DIMENSION_READINESS_DELTA_NAME", "DIMENSION_READINESS_NAME", "ELEMENT_ATTRIBUTES", "ELEMENT_DESCRIPTIONS", "ElementType", "ElementUid", "FC_RULES", "FM_RULES", "FileFactsSchema", "ImportEdgeSchema", "MAX_SLUG_LENGTH", "META_MODEL_VERSION", "MODELING_ELEMENT_TYPES", "MT_RULES", "MetricPolicySchema", "ND_RULES", "ONTOLOGY_VERSION", "OntologyElement", "OntologyGraph", "PHASE_READINESS_NAME", "PhaseGate", "REQUIRED_PATTERNS", "RULES_VERSION", "RULE_TO_DIMENSION", "RULE_TO_PHASE", "ReadinessDimension", "ReadinessReport", "ReadinessScore", "RealRefSchema", "RepoRelativePathSchema", "ReqKind", "RuleSeverity", "RuleViolation", "SC_RULES", "TRACE_PATTERNS", "TestRefSchema", "TestRefsSchema", "TestResult", "Trace", "TraceType", "UC_RULES", "V3_RULES", "VIEW_RULES", "VerificationMethod", "ViolationCandidate", "ViolationContext", "actionPriority", "allocationCohesion", "apMethod", "attributeTypeOf", "bq01Unambiguous", "bq02Verifiable", "bq04Necessary", "bq06Conforming", "bq07Complete", "bw02WhiteboxWidth", "cl01ConopsCompleteness", "cr01CrossingFlowCount", "decomposedFuncs", "evaluateAFRules", "evaluateAORules", "evaluateAllRules", "evaluateBQRules", "evaluateCRRules", "evaluateConformanceRules", "evaluateFCRules", "evaluateFMRules", "evaluateMTRules", "evaluateNDRules", "evaluateRules", "evaluateSCRules", "evaluateUCRules", "evaluateViewRules", "extractFormatE", "fc02LeafUcHasFchain", "fc03FchainFlat", "fc04ActorBounded", "fm01MissingFmeaAttributes", "fm02MissingMitigation", "fm03HighRiskUnverified", "funcSimilarity", "getRuleDefsForProfile", "hydrateAttrValue", "importCoverage", "indexOf", "io01CrossModuleCompleteness", "isElementUid", "isValidTrace", "jaccard", "maxOccurs", "minOccurs", "moduleMetrics", "mt01Instability", "mt02Lcom4", "nd01FuncNearDuplicate", "nd02SchemaNearDuplicate", "nfr01BudgetOvershoot", "normalizeReqKinds", "pairsAbove", "parseElementUid", "parseFormatE", "sc02IsReferenced", "schemaSimilarity", "serializeToFormatE", "setBQ04SimilarityMatrix", "toElementUid", "toEvaluableGraph", "tokens", "traceRejection", "tryParseElementUid", "uc01HasRequirements", "uc02HasActor", "uc03HasScenario", "uc04GoalDefined", "uc05HasPostcondition", "uc06HasPrecondition", "vr01TestNoResult"];
|
|
24
27
|
};
|