@sigloch/contracts 10.10.0 → 10.13.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/conformance-rules.d.ts +6 -1
- package/dist/se/conformance-rules.js +227 -49
- package/dist/se/cr-quality-rules.d.ts +5 -0
- package/dist/se/cr-quality-rules.js +78 -1
- package/dist/se/evaluate-all.d.ts +8 -1
- package/dist/se/evaluate-all.js +32 -29
- package/dist/se/fchain-quality-rules.d.ts +2 -1
- package/dist/se/fchain-quality-rules.js +132 -0
- package/dist/se/fmea-rules.js +22 -12
- package/dist/se/function-criticality.d.ts +8 -22
- package/dist/se/function-criticality.js +71 -1
- package/dist/se/grammar-snapshot.d.ts +9 -9
- package/dist/se/grammar-snapshot.js +34 -18
- package/dist/se/index.d.ts +3 -3
- package/dist/se/index.js +3 -3
- package/dist/se/meta-model.js +27 -16
- package/dist/se/metric-rules.d.ts +20 -61
- package/dist/se/metric-rules.js +90 -1
- package/dist/se/ontology.d.ts +69 -21
- package/dist/se/ontology.js +68 -16
- package/dist/se/readiness.d.ts +14 -0
- package/dist/se/readiness.js +33 -7
- package/dist/se/rule-help.js +28 -20
- package/dist/se/rules.d.ts +16 -0
- package/dist/se/rules.js +63 -64
- package/dist/se/uc-quality-rules.d.ts +0 -2
- package/dist/se/uc-quality-rules.js +2 -40
- package/dist/se/view-rules.js +5 -5
- package/package.json +1 -1
package/dist/se/ontology.d.ts
CHANGED
|
@@ -40,24 +40,27 @@ export declare const TraceType: z.ZodEnum<{
|
|
|
40
40
|
}>;
|
|
41
41
|
export type TraceType = z.infer<typeof TraceType>;
|
|
42
42
|
/**
|
|
43
|
-
* REQ kind —
|
|
43
|
+
* REQ kind — GENAU EIN Wert je REQ, aus zwei (CR-SM-366).
|
|
44
44
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
45
|
+
* `functional` -> erfuellt von FUNC. `non-functional` -> erfuellt von MOD (lokales Budget), SYS
|
|
46
|
+
* (Systemebene) oder FCHAIN (Ende-zu-Ende entlang der Kette). Ohne kinds kein Erfueller (BQ-07,
|
|
47
|
+
* `satisfiesPredicate`). Ein REQ, das beides ist, ist falsch zerlegt -> teilen; die
|
|
48
|
+
* Teilmengen-Semantik der where-Praedikate laesst es von niemandem erfuellen.
|
|
49
|
+
*
|
|
50
|
+
* Entfallen (Major, CR-SM-366):
|
|
51
|
+
* - `precondition` / `postcondition`: die Vorbedingung steckt im Eingangs-FLOW der Kette, die
|
|
52
|
+
* Nachbedingung ist das UC-Ziel — beides prueft R-21 (Integrationstest je Kette). Ihre Leser
|
|
53
|
+
* UC-05/06 sind seit CR-SM-357 gestrichen.
|
|
54
|
+
* - `risk` / `mitigation`: die FMEA-ROLLE einer Anforderung, keine Art — `REQ.attributes.role`
|
|
55
|
+
* (CR-SM-365), satisfy-neutral.
|
|
56
|
+
* Ein Altwert wird nicht still verworfen: `normalizeReqKinds` laesst ihn stehen, das Schema
|
|
57
|
+
* lehnt ihn ab, und R-18 meldet jede satisfy-Kante darauf als `kinds-mismatch` mit `declared`.
|
|
58
|
+
*
|
|
59
|
+
* Vorher CR-SM-266 B: `negative` entfiel (ein Verbots-REQ ist `functional`).
|
|
53
60
|
*/
|
|
54
61
|
export declare const ReqKind: z.ZodEnum<{
|
|
55
62
|
functional: "functional";
|
|
56
63
|
"non-functional": "non-functional";
|
|
57
|
-
risk: "risk";
|
|
58
|
-
mitigation: "mitigation";
|
|
59
|
-
precondition: "precondition";
|
|
60
|
-
postcondition: "postcondition";
|
|
61
64
|
}>;
|
|
62
65
|
export type ReqKind = z.infer<typeof ReqKind>;
|
|
63
66
|
/**
|
|
@@ -196,6 +199,58 @@ export declare const RealRefSchema: z.ZodObject<{
|
|
|
196
199
|
lang: z.ZodOptional<z.ZodString>;
|
|
197
200
|
}, z.core.$strip>;
|
|
198
201
|
export type RealRef = z.infer<typeof RealRefSchema>;
|
|
202
|
+
/**
|
|
203
|
+
* Was ein Attributvertrag an einem Element aussagt — dreiwertig (CR-SM-360).
|
|
204
|
+
*
|
|
205
|
+
* `absent` : das Attribut fehlt (auch als `null`-Grabstein — Attribute sind nur mergebar).
|
|
206
|
+
* `invalid` : es ist da, aber verletzt den Vertrag; `error` sagt wie.
|
|
207
|
+
* `bound` : es ist da und gueltig.
|
|
208
|
+
*
|
|
209
|
+
* Bis hierher parste jeder Leser selbst (25 Stellen in contracts und graphcode), und die Leser
|
|
210
|
+
* wichen ab: einer meldete ungueltige testRefs, die anderen behandelten „ungueltig" still wie
|
|
211
|
+
* „fehlt" — die Klasse aus CR-GC-338. Ein Aufrufer, der beides gleich behandeln will, tut das jetzt
|
|
212
|
+
* sichtbar (`state !== 'bound'`), statt dass der Unterschied beim Parsen verloren geht.
|
|
213
|
+
*/
|
|
214
|
+
export type BindingRead<T> = {
|
|
215
|
+
state: 'absent';
|
|
216
|
+
} | {
|
|
217
|
+
state: 'invalid';
|
|
218
|
+
error: string;
|
|
219
|
+
} | {
|
|
220
|
+
state: 'bound';
|
|
221
|
+
value: T;
|
|
222
|
+
};
|
|
223
|
+
type Attributes = Record<string, unknown> | undefined;
|
|
224
|
+
/** Der EINE Leser von `attributes.testRefs` (CR-SM-360). */
|
|
225
|
+
export declare function readTestRefs(attributes: Attributes): BindingRead<TestRefs>;
|
|
226
|
+
/** Der EINE Leser von `attributes.realRef` (CR-SM-360). */
|
|
227
|
+
export declare function readRealRef(attributes: Attributes): BindingRead<RealRef>;
|
|
228
|
+
/**
|
|
229
|
+
* CR-SM-364: die Kopplung eines Uebergangs — `FLOW.attributes.sync`. Fehlend heisst UNBEKANNT,
|
|
230
|
+
* nie stillschweigend `sync`: eine Kettenkennzahl (synchrone Tiefe, Engstellen-Grad) weist eine
|
|
231
|
+
* unmarkierte Kette als „nicht bewertbar" aus, statt sie ueber eine Annahme zu beurteilen.
|
|
232
|
+
*/
|
|
233
|
+
export declare const FlowSync: z.ZodEnum<{
|
|
234
|
+
sync: "sync";
|
|
235
|
+
async: "async";
|
|
236
|
+
}>;
|
|
237
|
+
export type FlowSync = z.infer<typeof FlowSync>;
|
|
238
|
+
/** Der EINE Leser von `FLOW.attributes.sync` (CR-SM-364) — ungueltig ist nicht fehlend. */
|
|
239
|
+
export declare function readFlowSync(attributes: Attributes): BindingRead<FlowSync>;
|
|
240
|
+
/**
|
|
241
|
+
* CR-SM-365: die ROLLE einer Anforderung im FMEA-Sinn — `REQ.attributes.role`. `risk` und
|
|
242
|
+
* `mitigation` waren bis hierher `kinds`-Werte und damit satisfy-relevant (MOD/SYS erfuellten
|
|
243
|
+
* sie). Sie sind aber keine ART der Anforderung, sondern ihre Motivation: eine Gegenmassnahme ist
|
|
244
|
+
* funktional oder nicht-funktional wie jede andere REQ. Die Rolle ist satisfy-neutral — die
|
|
245
|
+
* Grammatik (`isValidTrace`) liest sie nicht; FM-01..03 lesen NUR sie.
|
|
246
|
+
*/
|
|
247
|
+
export declare const ReqRole: z.ZodEnum<{
|
|
248
|
+
risk: "risk";
|
|
249
|
+
mitigation: "mitigation";
|
|
250
|
+
}>;
|
|
251
|
+
export type ReqRole = z.infer<typeof ReqRole>;
|
|
252
|
+
/** Der EINE Leser von `REQ.attributes.role` (CR-SM-365) — ungueltig ist nicht fehlend. */
|
|
253
|
+
export declare function readReqRole(attributes: Attributes): BindingRead<ReqRole>;
|
|
199
254
|
/**
|
|
200
255
|
* The five judgment-work artifact ids (CR-GC-221's creation keys) that graphcode's
|
|
201
256
|
* skills produce and that a phase gate checks for presence+freshness (CR-SM-227).
|
|
@@ -288,10 +343,6 @@ export declare const OntologyElement: z.ZodObject<{
|
|
|
288
343
|
kinds: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
289
344
|
functional: "functional";
|
|
290
345
|
"non-functional": "non-functional";
|
|
291
|
-
risk: "risk";
|
|
292
|
-
mitigation: "mitigation";
|
|
293
|
-
precondition: "precondition";
|
|
294
|
-
postcondition: "postcondition";
|
|
295
346
|
}>>>;
|
|
296
347
|
attributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
297
348
|
status: z.ZodDefault<z.ZodEnum<{
|
|
@@ -354,10 +405,6 @@ export declare const OntologyGraph: z.ZodObject<{
|
|
|
354
405
|
kinds: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
355
406
|
functional: "functional";
|
|
356
407
|
"non-functional": "non-functional";
|
|
357
|
-
risk: "risk";
|
|
358
|
-
mitigation: "mitigation";
|
|
359
|
-
precondition: "precondition";
|
|
360
|
-
postcondition: "postcondition";
|
|
361
408
|
}>>>;
|
|
362
409
|
attributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
363
410
|
status: z.ZodDefault<z.ZodEnum<{
|
|
@@ -409,3 +456,4 @@ export interface AttributeSpec {
|
|
|
409
456
|
* the prescribed keys that rules, views, and extractors rely on.
|
|
410
457
|
*/
|
|
411
458
|
export declare const ELEMENT_ATTRIBUTES: Partial<Record<ElementType, AttributeSpec[]>>;
|
|
459
|
+
export {};
|
package/dist/se/ontology.js
CHANGED
|
@@ -25,21 +25,25 @@ export const TraceType = z.enum([
|
|
|
25
25
|
'compose', 'io', 'satisfy', 'verify', 'allocate', 'relation',
|
|
26
26
|
]);
|
|
27
27
|
/**
|
|
28
|
-
* REQ kind —
|
|
28
|
+
* REQ kind — GENAU EIN Wert je REQ, aus zwei (CR-SM-366).
|
|
29
29
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
30
|
+
* `functional` -> erfuellt von FUNC. `non-functional` -> erfuellt von MOD (lokales Budget), SYS
|
|
31
|
+
* (Systemebene) oder FCHAIN (Ende-zu-Ende entlang der Kette). Ohne kinds kein Erfueller (BQ-07,
|
|
32
|
+
* `satisfiesPredicate`). Ein REQ, das beides ist, ist falsch zerlegt -> teilen; die
|
|
33
|
+
* Teilmengen-Semantik der where-Praedikate laesst es von niemandem erfuellen.
|
|
34
|
+
*
|
|
35
|
+
* Entfallen (Major, CR-SM-366):
|
|
36
|
+
* - `precondition` / `postcondition`: die Vorbedingung steckt im Eingangs-FLOW der Kette, die
|
|
37
|
+
* Nachbedingung ist das UC-Ziel — beides prueft R-21 (Integrationstest je Kette). Ihre Leser
|
|
38
|
+
* UC-05/06 sind seit CR-SM-357 gestrichen.
|
|
39
|
+
* - `risk` / `mitigation`: die FMEA-ROLLE einer Anforderung, keine Art — `REQ.attributes.role`
|
|
40
|
+
* (CR-SM-365), satisfy-neutral.
|
|
41
|
+
* Ein Altwert wird nicht still verworfen: `normalizeReqKinds` laesst ihn stehen, das Schema
|
|
42
|
+
* lehnt ihn ab, und R-18 meldet jede satisfy-Kante darauf als `kinds-mismatch` mit `declared`.
|
|
43
|
+
*
|
|
44
|
+
* Vorher CR-SM-266 B: `negative` entfiel (ein Verbots-REQ ist `functional`).
|
|
38
45
|
*/
|
|
39
|
-
export const ReqKind = z.enum([
|
|
40
|
-
'functional', 'non-functional', 'risk',
|
|
41
|
-
'mitigation', 'precondition', 'postcondition',
|
|
42
|
-
]);
|
|
46
|
+
export const ReqKind = z.enum(['functional', 'non-functional']);
|
|
43
47
|
/**
|
|
44
48
|
* `kinds` in der Form, die WIRKLICH auf Platte liegt — als Liste.
|
|
45
49
|
*
|
|
@@ -167,6 +171,52 @@ export const RealRefSchema = z.object({
|
|
|
167
171
|
symbol: z.string().optional(),
|
|
168
172
|
lang: z.string().optional(),
|
|
169
173
|
});
|
|
174
|
+
/** Der EINE Leser von `attributes.testRefs` (CR-SM-360). */
|
|
175
|
+
export function readTestRefs(attributes) {
|
|
176
|
+
const raw = attributes?.testRefs;
|
|
177
|
+
if (raw === undefined || raw === null)
|
|
178
|
+
return { state: 'absent' };
|
|
179
|
+
const r = TestRefsSchema.safeParse(raw);
|
|
180
|
+
return r.success ? { state: 'bound', value: r.data } : { state: 'invalid', error: r.error.message };
|
|
181
|
+
}
|
|
182
|
+
/** Der EINE Leser von `attributes.realRef` (CR-SM-360). */
|
|
183
|
+
export function readRealRef(attributes) {
|
|
184
|
+
const raw = attributes?.realRef;
|
|
185
|
+
if (raw === undefined || raw === null)
|
|
186
|
+
return { state: 'absent' };
|
|
187
|
+
const r = RealRefSchema.safeParse(raw);
|
|
188
|
+
return r.success ? { state: 'bound', value: r.data } : { state: 'invalid', error: r.error.message };
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* CR-SM-364: die Kopplung eines Uebergangs — `FLOW.attributes.sync`. Fehlend heisst UNBEKANNT,
|
|
192
|
+
* nie stillschweigend `sync`: eine Kettenkennzahl (synchrone Tiefe, Engstellen-Grad) weist eine
|
|
193
|
+
* unmarkierte Kette als „nicht bewertbar" aus, statt sie ueber eine Annahme zu beurteilen.
|
|
194
|
+
*/
|
|
195
|
+
export const FlowSync = z.enum(['sync', 'async']);
|
|
196
|
+
/** Der EINE Leser von `FLOW.attributes.sync` (CR-SM-364) — ungueltig ist nicht fehlend. */
|
|
197
|
+
export function readFlowSync(attributes) {
|
|
198
|
+
const raw = attributes?.sync;
|
|
199
|
+
if (raw === undefined || raw === null)
|
|
200
|
+
return { state: 'absent' };
|
|
201
|
+
const r = FlowSync.safeParse(raw);
|
|
202
|
+
return r.success ? { state: 'bound', value: r.data } : { state: 'invalid', error: r.error.message };
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* CR-SM-365: die ROLLE einer Anforderung im FMEA-Sinn — `REQ.attributes.role`. `risk` und
|
|
206
|
+
* `mitigation` waren bis hierher `kinds`-Werte und damit satisfy-relevant (MOD/SYS erfuellten
|
|
207
|
+
* sie). Sie sind aber keine ART der Anforderung, sondern ihre Motivation: eine Gegenmassnahme ist
|
|
208
|
+
* funktional oder nicht-funktional wie jede andere REQ. Die Rolle ist satisfy-neutral — die
|
|
209
|
+
* Grammatik (`isValidTrace`) liest sie nicht; FM-01..03 lesen NUR sie.
|
|
210
|
+
*/
|
|
211
|
+
export const ReqRole = z.enum(['risk', 'mitigation']);
|
|
212
|
+
/** Der EINE Leser von `REQ.attributes.role` (CR-SM-365) — ungueltig ist nicht fehlend. */
|
|
213
|
+
export function readReqRole(attributes) {
|
|
214
|
+
const raw = attributes?.role;
|
|
215
|
+
if (raw === undefined || raw === null)
|
|
216
|
+
return { state: 'absent' };
|
|
217
|
+
const r = ReqRole.safeParse(raw);
|
|
218
|
+
return r.success ? { state: 'bound', value: r.data } : { state: 'invalid', error: r.error.message };
|
|
219
|
+
}
|
|
170
220
|
/**
|
|
171
221
|
* The five judgment-work artifact ids (CR-GC-221's creation keys) that graphcode's
|
|
172
222
|
* skills produce and that a phase gate checks for presence+freshness (CR-SM-227).
|
|
@@ -247,7 +297,7 @@ export const OntologyElement = z.object({
|
|
|
247
297
|
description: z.string(),
|
|
248
298
|
/** INCOSE TIAD verification method — only for TEST elements (CR-057). */
|
|
249
299
|
method: VerificationMethod.optional(),
|
|
250
|
-
/** REQ kinds:
|
|
300
|
+
/** REQ kinds: exactly ONE of functional|non-functional (CR-SM-366); a list for the on-disk form. Only for REQ elements. */
|
|
251
301
|
kinds: z.array(ReqKind).optional(),
|
|
252
302
|
attributes: z.record(z.string(), z.unknown()).optional(),
|
|
253
303
|
status: z.enum(['draft', 'reviewed', 'open', 'done']).default('draft'),
|
|
@@ -319,6 +369,7 @@ export const ELEMENT_ATTRIBUTES = {
|
|
|
319
369
|
{ key: 'concept', type: 'boolean', description: 'Concept-only TEST: no run artifact yet; exempt from the R-19 testRefs-binding requirement (CR-GC-205)' },
|
|
320
370
|
],
|
|
321
371
|
REQ: [
|
|
372
|
+
{ key: 'role', type: 'enum', enumValues: ReqRole.options, description: "FMEA role: 'risk' | 'mitigation' — satisfy-neutral, read by FM-01..03 via readReqRole. A mitigation is functional or non-functional like any REQ; the role is its motivation, not its kind (CR-SM-365)" },
|
|
322
373
|
{ key: 'severity', type: 'number', description: 'FMEA severity (1-10)' },
|
|
323
374
|
{ key: 'occurrence', type: 'number', description: 'FMEA occurrence (1-10)' },
|
|
324
375
|
{ key: 'detection', type: 'number', description: 'FMEA detection (1-10)' },
|
|
@@ -340,9 +391,10 @@ export const ELEMENT_ATTRIBUTES = {
|
|
|
340
391
|
{ key: 'rationale', type: 'string', description: 'Reason for the change' },
|
|
341
392
|
{ key: 'spike', type: 'boolean', description: 'CR is a spike/exploration' },
|
|
342
393
|
],
|
|
394
|
+
// CR-SM-364: genau ein Realisierungsattribut. `protocol`/`qos` entfielen — freie Strings, in
|
|
395
|
+
// 0 von 186 Familien-FLOWs gesetzt, ohne Leser. Abweichende Kopplung je Verbraucher ⇒ FLOW teilen.
|
|
343
396
|
FLOW: [
|
|
344
|
-
{ key: '
|
|
345
|
-
{ key: 'qos', type: 'string', description: 'Quality of Service level' },
|
|
397
|
+
{ key: 'sync', type: 'enum', enumValues: FlowSync.options, description: "Coupling of the transition: 'sync' | 'async'. Missing = unknown, never an implicit 'sync' — read with readFlowSync (CR-SM-364)" },
|
|
346
398
|
],
|
|
347
399
|
MOD: [
|
|
348
400
|
{ key: 'path', type: 'string', description: 'Source file or glob the module owns, e.g. src/harness.ts — anchors the MOD<->file mapping for graph<->code conformance (CR-GC-205)' },
|
package/dist/se/readiness.d.ts
CHANGED
|
@@ -170,6 +170,20 @@ export type PhaseGateType = z.infer<typeof PhaseGate>;
|
|
|
170
170
|
* single-owner convention as RULE_TO_DIMENSION.
|
|
171
171
|
*/
|
|
172
172
|
export declare const RULE_TO_PHASE: Record<string, PhaseGateType>;
|
|
173
|
+
/**
|
|
174
|
+
* CR-SM-343 — die VORBEDINGUNG einer Regel: der Elementtyp, von dem der Graph mindestens ein
|
|
175
|
+
* Element tragen muss, damit die Regel ueberhaupt ausgewertet ist.
|
|
176
|
+
*
|
|
177
|
+
* Der Nenner einer Dimension ist `Σ Grundgesamtheit` ueber ihre Regeln (`domain`). Eine Regel,
|
|
178
|
+
* die mangels Gegenstand schweigt, truege dort ihre ganze Grundgesamtheit bei und liefert null
|
|
179
|
+
* Verstoesse — der Score STIEGE, weil nicht geprueft wurde. CR-R05 fragt nach einem Bauauftrag;
|
|
180
|
+
* ein Graph ohne einen einzigen CR (`cr: docs`) hat keinen Plan im Graphen, also ist die Frage
|
|
181
|
+
* dort NICHT GESTELLT, nicht bestanden. Wer einen Anteil bildet, fragt `ruleApplies` und laesst
|
|
182
|
+
* eine nicht anwendbare Regel aus Zaehler UND Nenner.
|
|
183
|
+
*/
|
|
184
|
+
export declare const RULE_PRECONDITION: Readonly<Record<string, string>>;
|
|
185
|
+
/** Ist die Regel an einem Graphen mit diesen Typ-Zaehlungen ausgewertet? (CR-SM-343) */
|
|
186
|
+
export declare function ruleApplies(ruleId: string, countByType: Readonly<Record<string, number>>): boolean;
|
|
173
187
|
/**
|
|
174
188
|
* Die Eigentuemer-Spalte (CR-SM-350, Entscheidung 2026-09-22): welcher TASK eine Regel bearbeitet.
|
|
175
189
|
*
|
package/dist/se/readiness.js
CHANGED
|
@@ -151,7 +151,10 @@ export const RULE_TO_DIMENSION = {
|
|
|
151
151
|
// req
|
|
152
152
|
'BQ-01': 'req', 'BQ-02': 'req', 'BQ-04': 'req',
|
|
153
153
|
'BQ-06': 'req', 'BQ-07': 'req',
|
|
154
|
-
'RD-01': 'req', 'RD-02': 'req',
|
|
154
|
+
'RD-01': 'req', 'RD-02': 'req',
|
|
155
|
+
// CR-SM-343: CR-R05 (Blatt-REQ ohne Bauauftrag) — ein Mangel der Anforderungsdeckung, nicht
|
|
156
|
+
// der CR-Hygiene; zaehlt nur, wenn der Graph ueberhaupt CR-Knoten traegt (RULE_PRECONDITION).
|
|
157
|
+
'CR-R05': 'req',
|
|
155
158
|
// RD-04 is decomposition *breadth* — an architecture concern, not a requirement one
|
|
156
159
|
'RD-04': 'arch',
|
|
157
160
|
// CR-SM-311: die Untergrenze derselben Breite — ebenfalls Architektur
|
|
@@ -168,10 +171,10 @@ export const RULE_TO_DIMENSION = {
|
|
|
168
171
|
'R-30': 'arch', 'R-31': 'arch',
|
|
169
172
|
// uc
|
|
170
173
|
'UC-01': 'uc', 'UC-02': 'uc', 'UC-03': 'uc', 'UC-04': 'uc',
|
|
171
|
-
'UC-05': 'uc', 'UC-06': 'uc',
|
|
172
174
|
'R-15': 'uc', 'R-16': 'uc', 'R-17': 'uc',
|
|
173
175
|
// FC-04 (CR-SM-226): FCHAIN actor-bounded (trigger+consumer) — same dimension as FC-01..03.
|
|
174
176
|
'FC-02': 'uc', 'FC-03': 'uc', 'FC-04': 'uc',
|
|
177
|
+
'FC-05': 'uc', // CR-SM-363: Zusammenhang der Kette — dieselbe Dimension wie FC-04
|
|
175
178
|
// arch
|
|
176
179
|
'R-02': 'arch', 'R-10': 'arch', 'R-12': 'arch',
|
|
177
180
|
// alloc
|
|
@@ -250,8 +253,8 @@ export const RULE_TO_PHASE = {
|
|
|
250
253
|
'TR-01': 'PDR', 'IR-01': 'PDR', // CR-SM-355: Task-Ausgaenge von trade / irr — dasselbe Gate wie ihr Eintritt
|
|
251
254
|
// SRR — requirements/scope clarity, system+UC boundary definition.
|
|
252
255
|
'BQ-01': 'SRR', 'BQ-02': 'SRR', 'BQ-04': 'SRR', 'BQ-06': 'SRR', 'BQ-07': 'SRR',
|
|
253
|
-
'RD-01': 'SRR', 'RD-02': 'SRR',
|
|
254
|
-
'UC-01': 'SRR', 'UC-02': 'SRR', 'UC-03': 'SRR', 'UC-04': 'SRR',
|
|
256
|
+
'RD-01': 'SRR', 'RD-02': 'SRR',
|
|
257
|
+
'UC-01': 'SRR', 'UC-02': 'SRR', 'UC-03': 'SRR', 'UC-04': 'SRR',
|
|
255
258
|
'R-16': 'SRR', 'R-17': 'SRR',
|
|
256
259
|
'FC-02': 'SRR',
|
|
257
260
|
'CL-01': 'SRR',
|
|
@@ -263,7 +266,7 @@ export const RULE_TO_PHASE = {
|
|
|
263
266
|
'R-02': 'PDR', 'R-08': 'PDR', 'R-10': 'PDR', 'R-12': 'PDR', 'R-18': 'PDR',
|
|
264
267
|
'R-04': 'PDR', 'R-22': 'PDR', 'R-23': 'PDR',
|
|
265
268
|
'R-15': 'PDR',
|
|
266
|
-
'FC-03': 'PDR', 'FC-04': 'PDR',
|
|
269
|
+
'FC-03': 'PDR', 'FC-04': 'PDR', 'FC-05': 'PDR',
|
|
267
270
|
// CR-GC-366: Anschluss des Funktionsbaus — gehoert an dasselbe Gate wie R-15/IO-01,
|
|
268
271
|
// die auf derselben Kette aufsetzen.
|
|
269
272
|
'R-30': 'PDR', 'R-31': 'PDR',
|
|
@@ -283,7 +286,27 @@ export const RULE_TO_PHASE = {
|
|
|
283
286
|
'VR-01': 'TRR',
|
|
284
287
|
'FM-03': 'TRR',
|
|
285
288
|
'CR-R02': 'TRR',
|
|
289
|
+
'CR-R05': 'TRR', // CR-SM-343: dieselbe Phase wie AF-05 (Implementierungsplan)
|
|
286
290
|
};
|
|
291
|
+
/**
|
|
292
|
+
* CR-SM-343 — die VORBEDINGUNG einer Regel: der Elementtyp, von dem der Graph mindestens ein
|
|
293
|
+
* Element tragen muss, damit die Regel ueberhaupt ausgewertet ist.
|
|
294
|
+
*
|
|
295
|
+
* Der Nenner einer Dimension ist `Σ Grundgesamtheit` ueber ihre Regeln (`domain`). Eine Regel,
|
|
296
|
+
* die mangels Gegenstand schweigt, truege dort ihre ganze Grundgesamtheit bei und liefert null
|
|
297
|
+
* Verstoesse — der Score STIEGE, weil nicht geprueft wurde. CR-R05 fragt nach einem Bauauftrag;
|
|
298
|
+
* ein Graph ohne einen einzigen CR (`cr: docs`) hat keinen Plan im Graphen, also ist die Frage
|
|
299
|
+
* dort NICHT GESTELLT, nicht bestanden. Wer einen Anteil bildet, fragt `ruleApplies` und laesst
|
|
300
|
+
* eine nicht anwendbare Regel aus Zaehler UND Nenner.
|
|
301
|
+
*/
|
|
302
|
+
export const RULE_PRECONDITION = {
|
|
303
|
+
'CR-R05': 'CR',
|
|
304
|
+
};
|
|
305
|
+
/** Ist die Regel an einem Graphen mit diesen Typ-Zaehlungen ausgewertet? (CR-SM-343) */
|
|
306
|
+
export function ruleApplies(ruleId, countByType) {
|
|
307
|
+
const required = RULE_PRECONDITION[ruleId];
|
|
308
|
+
return required === undefined || (countByType[required] ?? 0) > 0;
|
|
309
|
+
}
|
|
287
310
|
/**
|
|
288
311
|
* Die Eigentuemer-Spalte (CR-SM-350, Entscheidung 2026-09-22): welcher TASK eine Regel bearbeitet.
|
|
289
312
|
*
|
|
@@ -303,10 +326,13 @@ export const TASK_OWNED_RULES = {
|
|
|
303
326
|
trade: ['TR-01'], // CR-SM-355: Trade-Entscheidung als CR
|
|
304
327
|
irr: ['IR-01'], // CR-SM-355: Annahmen-Review promoviert zu CR
|
|
305
328
|
fmea: ['FM-01', 'FM-02', 'FM-03'],
|
|
306
|
-
|
|
329
|
+
// CR-SM-377: CR-R05 (Blatt-REQ ohne Bauauftrag, CR-SM-343) fragt nach einem CR — die Antwort
|
|
330
|
+
// schreibt der Plan-Task (se-plan), nicht die Generierungsschleife. FC-05 bleibt Kern: die
|
|
331
|
+
// Kette zu schliessen ist Spezifikationsarbeit wie FC-04.
|
|
332
|
+
plan: ['MS-01', 'MS-02', 'MS-03', 'CR-R01', 'CR-R02', 'CR-R03', 'CR-R05'],
|
|
307
333
|
// Annahme (CR-SM-350): BQ bekommt einen eigenen Task, vorerst ohne automatischen Eintrittspunkt.
|
|
308
334
|
anforderungsqualitaet: ['BQ-01', 'BQ-02', 'BQ-04', 'BQ-06', 'BQ-07'],
|
|
309
|
-
realisierung: ['R-19', 'R-20', 'R-26', 'R-29', 'R-32', 'VR-01', 'RC-01', 'RC-02', 'RC-03', 'RC-04', 'RC-05', 'RC-06', 'RC-07'],
|
|
335
|
+
realisierung: ['R-19', 'R-20', 'R-26', 'R-29', 'R-32', 'VR-01', 'RC-01', 'RC-02', 'RC-03', 'RC-04', 'RC-05', 'RC-06', 'RC-07', 'RC-08', 'RC-09', 'RC-10'],
|
|
310
336
|
};
|
|
311
337
|
/**
|
|
312
338
|
* Der Eintrittspunkt eines Tasks im Kern: die Regel, die "dieses Artefakt fehlt" sagt. `null` = der
|
package/dist/se/rule-help.js
CHANGED
|
@@ -115,6 +115,11 @@ export const RULE_HELP = {
|
|
|
115
115
|
plain: "Several open changes touch the same thing, so they will collide → sequence them or merge them.",
|
|
116
116
|
se: "One element tracked by more than one `CR` with `status` open/in-progress.",
|
|
117
117
|
},
|
|
118
|
+
'CR-R05': {
|
|
119
|
+
plain: "This smallest-piece requirement has no work order — no change request points at it or at the function that fulfils it, and that function is not built yet, so no plan will ever build it → attach it to the change request that builds it.",
|
|
120
|
+
se: "Leaf `REQ` (no `compose`→`REQ` children) with no build order: no `CR -relation->` on the REQ itself nor on a `FUNC` that `satisfy`s it (CR-SM-343; the REQ side of CR-R01). A `FUNC` that is already built — valid `realRef` or `external`, not `concept` — covers the REQ without a CR (CR-SM-375). A CR on a `MOD`/`SYS` carrier does not count — a module is a container; such REQs take a direct `CR -relation-> REQ`. Silent, and not scored, on a graph without any `CR` node (`RULE_PRECONDITION`).",
|
|
121
|
+
prompt: "se-plan",
|
|
122
|
+
},
|
|
118
123
|
'FC-02': {
|
|
119
124
|
plain: "A scenario that is not broken into sub-scenarios has no described sequence of steps → add one, even if the steps are done by hand.",
|
|
120
125
|
se: "Leaf `UC` (no `UC -compose-> UC`) with no `FCHAIN`. A chain may consist of EXISTING FUNCs an actor strings together — it costs a node plus compose edges, not code.",
|
|
@@ -128,19 +133,23 @@ export const RULE_HELP = {
|
|
|
128
133
|
plain: "A sequence either has nobody starting it or nothing coming back out → wire both ends to whoever uses it.",
|
|
129
134
|
se: "`FCHAIN` lacking an entry (`ACTOR -io-> FLOW -io-> FUNC∈chain`) or an exit (`FUNC∈chain -io-> FLOW -io-> ACTOR`). Stricter than FC-01: both directions, at FUNC/FLOW level, no UC-level bypass.",
|
|
130
135
|
},
|
|
136
|
+
'FC-05': {
|
|
137
|
+
plain: "The steps of this sequence do not hand their results to each other — it falls apart into pieces, so nobody can say how long it is or where it gets stuck → add the missing step, connect the pieces with a data flow, or split it into separate sequences.",
|
|
138
|
+
se: "`FCHAIN` whose member `FUNC`s do not form one (weakly) connected component along producer → consumer (`FUNC -io-> FLOW -io-> FUNC`, both ends members). Per side component the cause: `missing-link` (main and side part are joined through a `FUNC` outside the chain — compose it) or `bag` (no FUNC joins them: a missing FLOW between members, or parallel services at a shared source — split). One finding per chain, components in `context.side_components` (CR-SM-242). Silent while any member lacks an io input or output (R-31 first); entry/exit belong to FC-04 (CR-SM-363).",
|
|
139
|
+
},
|
|
131
140
|
'FM-01': {
|
|
132
141
|
plain: "A requirement is marked as a risk but carries no risk ratings → rate how bad, how likely and how detectable it is (1-10 each).",
|
|
133
|
-
se: "
|
|
142
|
+
se: "`REQ` with `role:\"risk\"` missing `severity` / `occurrence` / `detection` attributes (AIAG-VDA). The role is the requirement's motivation, not its kind — satisfy-neutral (CR-SM-365).",
|
|
134
143
|
prompt: "se-fmea",
|
|
135
144
|
},
|
|
136
145
|
'FM-02': {
|
|
137
146
|
plain: "A known risk has nothing planned against it → write the countermeasure as its own requirement.",
|
|
138
|
-
se: "
|
|
147
|
+
se: "`REQ` with `role:\"risk\"` and no `compose`d `REQ` with `role:\"mitigation\"`. The mitigation keeps its own kind (functional or non-functional) and is satisfied like any REQ of that kind (CR-SM-365).",
|
|
139
148
|
prompt: "se-fmea",
|
|
140
149
|
},
|
|
141
150
|
'FM-03': {
|
|
142
151
|
plain: "A high risk has no test that actually passed → add a test proving the countermeasure works.",
|
|
143
|
-
se: "
|
|
152
|
+
se: "`REQ` with `role:\"risk\"`, Action Priority High (AIAG-VDA, RPN band as interim) and no verifying `TEST` whose every `testRefs` entry has `result:\"passed\"`.",
|
|
144
153
|
prompt: "se-fmea",
|
|
145
154
|
},
|
|
146
155
|
'IO-01': {
|
|
@@ -247,8 +256,8 @@ export const RULE_HELP = {
|
|
|
247
256
|
se: "Realized `FUNC` with no valid `realRef` `{file, symbol}` (graph↔code binding); else `concept:true` / `external:true`.",
|
|
248
257
|
},
|
|
249
258
|
'R-21': {
|
|
250
|
-
plain: "Two functions hand data over, but they are not in one chain together — or they are, and
|
|
251
|
-
se: "FUNC↔FUNC handover (`FUNC` ─io→ `FLOW` ─io→ `FUNC`), two findings. (a) endpoints share NO `FCHAIN` → finding at the PRODUCER: no integration scope is declared. (b) endpoints share one, but no shared chain
|
|
259
|
+
plain: "Two functions hand data over, but they are not in one chain together — or they are, and the chain is not covered: some function in it has no requirement, and no end-to-end test checks the chain → give each function of the chain a requirement it fulfils, or give the chain an end-to-end quality requirement and a test for it.",
|
|
260
|
+
se: "FUNC↔FUNC handover (`FUNC` ─io→ `FLOW` ─io→ `FUNC`), two findings. (a) endpoints share NO `FCHAIN` → finding at the PRODUCER: no integration scope is declared. (b) endpoints share one, but no shared chain is covered → finding at the chain, naming the member FUNCs without a REQ. A chain is covered either (1) through its members — EVERY member FUNC (`FCHAIN` ─compose→ `FUNC`) satisfies at least one `REQ`; verifying those REQs is R-01's job (CR-SM-376) — or (2) end-to-end — a verified integration test (`TEST` ─verify→ `REQ` ←satisfy─ `FCHAIN`); an `FCHAIN` satisfies only non-functional REQs (CR-SM-366). SILENT when either endpoint is in no chain at all (that is R-30's statement) and when either is infrastructure (`chains >= policy.criticality.infrastructure`): a handover into a function that runs through every chain is a bus, not a missing test.",
|
|
252
261
|
},
|
|
253
262
|
'R-22': {
|
|
254
263
|
plain: "A function isn't assigned to any building block, so it has no home in the structure → put it on a module.",
|
|
@@ -300,7 +309,19 @@ export const RULE_HELP = {
|
|
|
300
309
|
},
|
|
301
310
|
'RC-07': {
|
|
302
311
|
plain: "A change request is marked done in the model but still open in the folder (or the other way round), or an open change request has no entry in the model → the folder decides; fix the model.",
|
|
303
|
-
se: "`CR` node whose `status` (closed = done
|
|
312
|
+
se: "`CR` node whose `status` (closed = done; CR-SM-362) contradicts `docs/cr/open|done/`, or an OPEN CR file with no `CR` node (anchored at the first `SYS`). Nodes without a file are not reported — history. Absent `crFiles` is SILENCE (CR-SM-329).",
|
|
313
|
+
},
|
|
314
|
+
'RC-08': {
|
|
315
|
+
plain: "A data contract in the model points at a type, which vanishes at runtime → write it as a Zod schema, so whoever produces the data can prove it and whoever reads it can check it.",
|
|
316
|
+
se: "`SCHEMA` whose `realRef` symbol is declared but is not a Zod schema (extractor field `zodSymbols`). Every producer needs a checkable schema — \"nobody parses it\" only means the reader is not known yet. Absent `zodSymbols` is SILENCE. Owns the type-binding cause: RC-04 stays quiet on such a SCHEMA (CR-SM-358).",
|
|
317
|
+
},
|
|
318
|
+
'RC-09': {
|
|
319
|
+
plain: "Code somewhere reads a data contract on its own, but the model does not know that place → go through the one translator the model names, or add the new translator to the model.",
|
|
320
|
+
se: "Zod-bound `SCHEMA` parsed (import + `.parse`/`.safeParse`) in a file that is neither its definition nor the `realRef` of a `FUNC` io-connected to a `FLOW` of this SCHEMA. The first code → model check: a second translator of one contract is a parallel path (spike CR-GC-637 — such paths share a contract, they are not similar). One finding per SCHEMA; test files exempt; runs only with `fileScope: 'all'` (CR-SM-358).",
|
|
321
|
+
},
|
|
322
|
+
'RC-10': {
|
|
323
|
+
plain: "No file in the code can be assigned to this building block, so nobody can check whether its imports cross boundaries the model does not know → give the block its source folder, or point one of its functions at its code.",
|
|
324
|
+
se: "`MOD` with neither a `path` attribute nor an allocated `FUNC` carrying a bound `realRef` — the only two ways a file resolves to a module. Without either, RC-05 and the boundary measurement are blind for this module by construction (sigllm: 0 RC-05 findings at 19 % import coverage, 8 at 81 %). The message names the cost from `importCoverage`. `concept`/`external` modules are exempt, as for R-20 (CR-SM-344).",
|
|
304
325
|
},
|
|
305
326
|
'RD-01': {
|
|
306
327
|
plain: "A smallest-piece feature has nothing built to fulfil it → add what implements it.",
|
|
@@ -311,10 +332,6 @@ export const RULE_HELP = {
|
|
|
311
332
|
plain: "You split a feature into smaller features but you're also building the big one directly → build only the small pieces, not both.",
|
|
312
333
|
se: "Parent `REQ` (has `compose`→`REQ` children) carrying a direct `FUNC` `satisfy`; the satisfy belongs on the children.",
|
|
313
334
|
},
|
|
314
|
-
'RD-03': {
|
|
315
|
-
plain: "You split a feature into pieces, but all the pieces are handled by the same one thing — the split may be pointless → consider merging them.",
|
|
316
|
-
se: "Parent `REQ` whose children all share one satisfier.",
|
|
317
|
-
},
|
|
318
335
|
'RD-04': {
|
|
319
336
|
plain: "One thing has more than 9 parts directly under it → group them, so each level stays readable.",
|
|
320
337
|
se: "Decomposition breadth above `metricPolicy.decompositionBreadth.warning` children on one level — `FUNC` `compose` `FUNC`, `SYS` `compose` `MOD`, a `MOD`'s sub-`MOD`s plus its own leaf `FUNC` (`allocate`), and the root `FUNC` forest anchored at `SYS` (CR-SM-282). Default 9, the upper end of 7±2 (CR-SM-296). CR-SM-311: a module level counts its own functions again — breadth, not size; module coupling is R-04. The lower bound is RD-05.",
|
|
@@ -334,8 +351,7 @@ export const RULE_HELP = {
|
|
|
334
351
|
},
|
|
335
352
|
'UC-02': {
|
|
336
353
|
plain: "A scenario has nobody who triggers it → name who or what starts it.",
|
|
337
|
-
se: "`UC`
|
|
338
|
-
prompt: "se:author-uc",
|
|
354
|
+
se: "`UC` that no `ACTOR` reaches: the one legal path is `ACTOR -io-> FLOW -io-> FUNC` (or back, `FUNC -io-> FLOW -io-> ACTOR`), the FUNC a member of one of the UC's chains (`UC -compose-> FCHAIN -compose-> FUNC`). A direct `ACTOR -io-> UC` is rejected by R-18. No skill prompt (CR-SM-370): `se:author-uc` shows creating UCs and `se:author-actor` says to leave actors unwired — neither is this work.",
|
|
339
355
|
},
|
|
340
356
|
'UC-03': {
|
|
341
357
|
plain: "A scenario says what should be possible but not how it runs → describe the steps as a chain of functions.",
|
|
@@ -347,14 +363,6 @@ export const RULE_HELP = {
|
|
|
347
363
|
se: "`UC` description shorter than 10 characters or containing TBD/TODO/FIXME/placeholder/XXX. Description IS the goal (CR-150).",
|
|
348
364
|
prompt: "se:author-uc",
|
|
349
365
|
},
|
|
350
|
-
'UC-05': {
|
|
351
|
-
plain: "A scenario does not say what must be true once it has finished → add that as a requirement.",
|
|
352
|
-
se: "`UC` with no `compose`d `REQ` carrying `kinds:[\"postcondition\"]`.",
|
|
353
|
-
},
|
|
354
|
-
'UC-06': {
|
|
355
|
-
plain: "A scenario does not say what must be true before it can start → add that as a requirement.",
|
|
356
|
-
se: "`UC` with no `compose`d `REQ` carrying `kinds:[\"precondition\"]`.",
|
|
357
|
-
},
|
|
358
366
|
'VR-01': {
|
|
359
367
|
plain: "A test exists but no result was ever recorded, so nobody knows if it passed → record the outcome.",
|
|
360
368
|
se: "`TEST` with no `testResult` attribute — assumed pending, never assumed green.",
|
package/dist/se/rules.d.ts
CHANGED
|
@@ -81,6 +81,14 @@ export declare const ViolationContext: z.ZodObject<{
|
|
|
81
81
|
parent_module: z.ZodOptional<z.ZodString>;
|
|
82
82
|
current_description: z.ZodOptional<z.ZodString>;
|
|
83
83
|
also_affects: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
84
|
+
side_components: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
85
|
+
members: z.ZodArray<z.ZodString>;
|
|
86
|
+
cause: z.ZodEnum<{
|
|
87
|
+
"missing-link": "missing-link";
|
|
88
|
+
bag: "bag";
|
|
89
|
+
}>;
|
|
90
|
+
via: z.ZodArray<z.ZodString>;
|
|
91
|
+
}, z.core.$strip>>>;
|
|
84
92
|
trace_rejection: z.ZodOptional<z.ZodObject<{
|
|
85
93
|
reason: z.ZodEnum<{
|
|
86
94
|
"no-pattern": "no-pattern";
|
|
@@ -212,6 +220,14 @@ export declare const RuleViolation: z.ZodObject<{
|
|
|
212
220
|
parent_module: z.ZodOptional<z.ZodString>;
|
|
213
221
|
current_description: z.ZodOptional<z.ZodString>;
|
|
214
222
|
also_affects: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
223
|
+
side_components: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
224
|
+
members: z.ZodArray<z.ZodString>;
|
|
225
|
+
cause: z.ZodEnum<{
|
|
226
|
+
"missing-link": "missing-link";
|
|
227
|
+
bag: "bag";
|
|
228
|
+
}>;
|
|
229
|
+
via: z.ZodArray<z.ZodString>;
|
|
230
|
+
}, z.core.$strip>>>;
|
|
215
231
|
trace_rejection: z.ZodOptional<z.ZodObject<{
|
|
216
232
|
reason: z.ZodEnum<{
|
|
217
233
|
"no-pattern": "no-pattern";
|