@sigloch/contracts 10.1.0 → 10.3.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.js +6 -3
- package/dist/se/function-criticality.d.ts +75 -0
- package/dist/se/function-criticality.js +50 -0
- package/dist/se/grammar-snapshot.d.ts +7 -7
- package/dist/se/grammar-snapshot.js +13 -5
- package/dist/se/index.d.ts +8 -2
- package/dist/se/index.js +8 -2
- package/dist/se/meta-model.js +2 -0
- package/dist/se/policy.d.ts +4 -5
- package/dist/se/policy.js +37 -26
- package/dist/se/readiness.d.ts +0 -2
- package/dist/se/readiness.js +10 -8
- package/dist/se/rule-help.js +18 -6
- package/dist/se/rules.js +261 -130
- package/package.json +1 -1
package/dist/se/policy.js
CHANGED
|
@@ -45,8 +45,20 @@ export const MetricPolicySchema = z.object({
|
|
|
45
45
|
* graphcode-Selbstmodell 20 zusaetzliche Befunde erzeugt, und `readiness` zaehlt `info`
|
|
46
46
|
* ungefiltert in den Nenner (`score = 1 - Verstoesse / applicable`) — genau der Grund, aus dem
|
|
47
47
|
* MT-03 zur Messung statt zur Regel wurde. Wer doktrin-streng fahren will, setzt 5.
|
|
48
|
+
*
|
|
49
|
+
* CR-SM-311: die Breite ist ein BAND. `min` ist die Untergrenze (Z3, ITEM-2026-053): eine Ebene
|
|
50
|
+
* mit weniger Elementen abstrahiert nichts. Beide Grenzen sind Pflicht, beide exklusiv — `min`
|
|
51
|
+
* und `warning` selbst liegen im Band.
|
|
48
52
|
*/
|
|
49
|
-
decompositionBreadth: z
|
|
53
|
+
decompositionBreadth: z
|
|
54
|
+
.object({
|
|
55
|
+
/** Unter `min` Kindern ist eine Ebene entartet. */
|
|
56
|
+
min: z.number().int().min(1),
|
|
57
|
+
/** Ueber `warning` Kindern ist eine Ebene zu breit. */
|
|
58
|
+
warning: z.number().int().min(2),
|
|
59
|
+
})
|
|
60
|
+
.refine((b) => b.min <= b.warning, { message: 'decompositionBreadth.min must not exceed decompositionBreadth.warning' })
|
|
61
|
+
.nullable(),
|
|
50
62
|
/**
|
|
51
63
|
* CR-SM-283: Randbreite je Blackbox (BW-02) — verschiedene Vertraege, die den Rand queren.
|
|
52
64
|
* Bewusst OHNE `info`-Stufe: die Verteilung gibt sie nicht her. bok und graph-view-edit enden
|
|
@@ -55,6 +67,26 @@ export const MetricPolicySchema = z.object({
|
|
|
55
67
|
* aus dem MT-03 zur Messung statt zur Regel wurde. `null` -> messen, nicht urteilen.
|
|
56
68
|
*/
|
|
57
69
|
boundaryWidth: z.object({ warning: z.number().int().min(1) }).nullable(),
|
|
70
|
+
/**
|
|
71
|
+
* CR-SM-314: ab wie vielen Wirkketten gilt eine FUNC als INFRASTRUKTUR.
|
|
72
|
+
*
|
|
73
|
+
* Die Zahl selbst (`functionCriticality`) urteilt nie — sie steht in jeder FUNC-Zeile. Diese
|
|
74
|
+
* Schwelle sagt nur, wo eine Regel sie als Ausnahme lesen darf; erster Abnehmer ist R-21
|
|
75
|
+
* (CR-SM-313): eine Uebergabe an eine Funktion, die quer durch alle Ketten laeuft, ist kein
|
|
76
|
+
* fehlender Integrationstest, sondern ein Bus.
|
|
77
|
+
*
|
|
78
|
+
* ABGELESEN, nicht gesetzt — aber nicht an der Verteilungsform. Die ist ein duenner Schwanz
|
|
79
|
+
* (17 Familiengraphen: 224 FUNCs in 1 Kette, 37 in 2, 6 in 3, 8 in 4, je 1 in 5/6/11) und gibt
|
|
80
|
+
* wie bei `instability` keine Schwelle her (CR-SM-293). Ablesbar ist die WIRKUNG: auf
|
|
81
|
+
* graphcodes 31 kettenlose Uebergaben stellen die Schwellen 3 und 4 identisch 19 frei, 5 und 6
|
|
82
|
+
* identisch 6. Ein Plateau von 3 bis 4 — innerhalb dessen die Wahl wirkungsfrei ist. Der
|
|
83
|
+
* Startwert ist seine Untergrenze.
|
|
84
|
+
*
|
|
85
|
+
* `min(2)`, nicht `min(1)`: bei 1 waere JEDE FUNC in einer Kette Infrastruktur, und die
|
|
86
|
+
* Ausnahme fraesse ihre eigene Regel. `null` -> keine FUNC gilt als Infrastruktur; die Zahl
|
|
87
|
+
* bleibt trotzdem gemessen.
|
|
88
|
+
*/
|
|
89
|
+
criticality: z.object({ infrastructure: z.number().int().min(2) }).nullable(),
|
|
58
90
|
/**
|
|
59
91
|
* FM-03: RPN (severity · occurrence · detection), ab dem ein Risiko-REQ eine bestandene
|
|
60
92
|
* Verifikation braucht (exklusiv). null → FM-03 feuert nie.
|
|
@@ -75,23 +107,6 @@ export const MetricPolicySchema = z.object({
|
|
|
75
107
|
* exportierten Graphen steht sie nie** (Zellwerte sind normative Wertung, keine Fakten).
|
|
76
108
|
*/
|
|
77
109
|
apTable: ApTableSchema.nullable(),
|
|
78
|
-
/**
|
|
79
|
-
* R-04: Modulgröße **gegen** Kreuzungen — die Regel wägt beides ab, ihr alter Name
|
|
80
|
-
* („Max module size") gab das nicht her. null → R-04 feuert nie.
|
|
81
|
-
*
|
|
82
|
-
* Drei Werte, weil die Regel drei Urteile fällt. Ein einzelner Schwellwert hätte zwei davon
|
|
83
|
-
* im Code gelassen — genau der Zustand, den dieser CR beseitigt.
|
|
84
|
-
*/
|
|
85
|
-
moduleSize: z
|
|
86
|
-
.object({
|
|
87
|
-
/** > `large` FUNCs: mit Kreuzungen warning, ohne Kreuzungen info („kohäsiv, nur groß"). */
|
|
88
|
-
large: z.number().int().min(1),
|
|
89
|
-
/** > `coupled` FUNCs ist die Untergrenze, ab der die Regel überhaupt hinsieht. */
|
|
90
|
-
coupled: z.number().int().min(1),
|
|
91
|
-
/** Kreuzungen, ab denen ein nur `coupled`-großes Modul warnt (exklusiv). */
|
|
92
|
-
crossings: z.number().int().min(0),
|
|
93
|
-
})
|
|
94
|
-
.nullable(),
|
|
95
110
|
});
|
|
96
111
|
/**
|
|
97
112
|
* Der Startwert, sichtbar als solcher — **kein** Fallback in der Regel.
|
|
@@ -133,17 +148,13 @@ export const DEFAULT_METRIC_POLICY = {
|
|
|
133
148
|
// weil `info` bei 5 den readiness-Nenner verwaessert haette; das Argument traegt fuer die
|
|
134
149
|
// OBERgrenze nicht, denn RD-04 meldet als `warning`. Die Zahl steht jetzt an EINER Stelle und
|
|
135
150
|
// gilt fuer beide Zerlegungsfragen -- Sub-FUNC und Sub-MOD.
|
|
136
|
-
|
|
151
|
+
// CR-SM-311: Untergrenze 3 — eine Ebene mit weniger Elementen ist entartet (Z3).
|
|
152
|
+
decompositionBreadth: { min: 3, warning: 9 },
|
|
137
153
|
// CR-SM-283: aus der Verteilung abgelesen — bok/gve max 3, graphcode 19, moneyflow 17.
|
|
138
154
|
boundaryWidth: { warning: 5 },
|
|
155
|
+
// CR-SM-314: Untergrenze des gemessenen Plateaus 3..4 (siehe Feldkommentar oben).
|
|
156
|
+
criticality: { infrastructure: 3 },
|
|
139
157
|
riskRpn: 100,
|
|
140
|
-
// `large`/`coupled`/`crossings` = die drei Literale aus `maxModuleSize`: vorher
|
|
141
|
-
// `funcCount <= 8` → skip, `funcCount > 12` → groß, `crossings > 2` → gekoppelt.
|
|
142
|
-
// CR-SM-296: an dieselbe Doktrin gebunden statt danebengesetzt. R-04 ist seit diesem CR ALLEIN
|
|
143
|
-
// fuer die Modulgroesse zustaendig (RD-04 hat ihr Allokations-Bein abgegeben), also gilt hier
|
|
144
|
-
// dieselbe 7+-2: `large` = 9 (Obergrenze), `coupled` = 7 (Untergrenze, ab der die Regel
|
|
145
|
-
// hinsieht). Vorher 12/8 -- zwei Zahlen fuer dieselbe Frage, unverbunden mit den 11 darueber.
|
|
146
|
-
moduleSize: { large: 9, coupled: 7, crossings: 2 },
|
|
147
158
|
// CR-SM-229: kein Startwert möglich und keiner gewollt — die Tabelle steht nur im Handbook.
|
|
148
159
|
// `null` heißt hier nicht „aus", sondern „markierter Übergang": bestätigte AP-Invarianten,
|
|
149
160
|
// sonst RPN-Bänder. `apMethod()` macht das für den Leser sichtbar.
|
package/dist/se/readiness.d.ts
CHANGED
|
@@ -34,7 +34,6 @@ export declare const ReadinessScore: z.ZodObject<{
|
|
|
34
34
|
violations: z.ZodNumber;
|
|
35
35
|
applicable: z.ZodNumber;
|
|
36
36
|
coreApplicable: z.ZodNumber;
|
|
37
|
-
ready: z.ZodBoolean;
|
|
38
37
|
}, z.core.$strip>;
|
|
39
38
|
export type ReadinessScoreType = z.infer<typeof ReadinessScore>;
|
|
40
39
|
/**
|
|
@@ -62,7 +61,6 @@ export declare const ReadinessReport: z.ZodObject<{
|
|
|
62
61
|
violations: z.ZodNumber;
|
|
63
62
|
applicable: z.ZodNumber;
|
|
64
63
|
coreApplicable: z.ZodNumber;
|
|
65
|
-
ready: z.ZodBoolean;
|
|
66
64
|
}, z.core.$strip>>;
|
|
67
65
|
timestamp: z.ZodISODateTime;
|
|
68
66
|
}, z.core.$strip>;
|
package/dist/se/readiness.js
CHANGED
|
@@ -44,10 +44,9 @@ export const ReadinessScore = z.object({
|
|
|
44
44
|
* Unterscheidung, an der der dokumentierte Ausweg aus CR-SM-237 gescheitert ist.
|
|
45
45
|
*/
|
|
46
46
|
coreApplicable: z.number().int(),
|
|
47
|
-
// CR-SM-
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
ready: z.boolean(),
|
|
47
|
+
// CR-SM-310: kein `ready` mehr. Ob eine Dimension zu schwach ist, urteilt der Konsument mit
|
|
48
|
+
// SEINER Schwelle (graphcode: generate.ts, focusThreshold aus der Config). Die Messung traegt
|
|
49
|
+
// kein Urteil — vorher stand es zweimal: hier als `ready` und beim Konsumenten.
|
|
51
50
|
});
|
|
52
51
|
/**
|
|
53
52
|
* CR-SM-237: `overallScore` ist weg. Es war das **ungewichtete** Mittel der acht
|
|
@@ -96,12 +95,14 @@ export const RULE_TO_DIMENSION = {
|
|
|
96
95
|
'RD-01': 'req', 'RD-02': 'req', 'RD-03': 'req',
|
|
97
96
|
// RD-04 is decomposition *breadth* — an architecture concern, not a requirement one
|
|
98
97
|
'RD-04': 'arch',
|
|
98
|
+
// CR-SM-311: die Untergrenze derselben Breite — ebenfalls Architektur
|
|
99
|
+
'RD-05': 'arch',
|
|
99
100
|
// trace/realization/allocation completeness rules (CR-228 D: previously unmapped → advisory fall-through)
|
|
100
101
|
'R-18': 'arch', 'R-19': 'ver', 'R-20': 'arch', 'R-21': 'ver',
|
|
101
102
|
// CR-SM-231: R-29 (Testdatei-Exklusivitaet) gehoert zu 'ver' wie R-19 — beide bewerten die
|
|
102
103
|
// Evidenz-Bindung einer Abnahme, R-19 ihre Praesenz, R-29 ihre Eindeutigkeit.
|
|
103
104
|
'R-29': 'ver',
|
|
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
|
|
105
|
+
'R-22': 'alloc', 'R-23': 'alloc', 'R-26': 'schema', 'R-32': 'ver', // CR-GC-366: R-30 (Wirkketten-Bindung) und R-31 (io-Verdrahtung) bewerten beide, ob ein
|
|
105
106
|
// Funktionsblock ueberhaupt im Bauplan haengt — dieselbe Dimension wie R-20 (realRef).
|
|
106
107
|
// NICHT 'uc': R-14..R-17 fragen, ob ein Behaelter gefuellt ist;
|
|
107
108
|
// diese beiden fragen von der FUNC aus, ob sie angeschlossen ist.
|
|
@@ -149,6 +150,7 @@ export const RULE_TO_DIMENSION = {
|
|
|
149
150
|
'NFR-01': 'arch',
|
|
150
151
|
// cross-module IO (CR-192)
|
|
151
152
|
'IO-01': 'arch',
|
|
153
|
+
'IO-02': 'arch', // CR-SM-307: Flusstopologie, dieselbe Dimension wie R-10/IO-01.
|
|
152
154
|
// view rules (CR-184)
|
|
153
155
|
'VR-01': 'ver',
|
|
154
156
|
'CL-01': 'uc',
|
|
@@ -189,7 +191,7 @@ export const RULE_TO_PHASE = {
|
|
|
189
191
|
'CR-R01': 'SRR', 'CR-R03': 'SRR',
|
|
190
192
|
'MS-01': 'SRR', 'MS-02': 'SRR', 'MS-03': 'SRR',
|
|
191
193
|
// PDR — architecture/functional completeness.
|
|
192
|
-
'RD-04': 'PDR',
|
|
194
|
+
'RD-04': 'PDR', 'RD-05': 'PDR',
|
|
193
195
|
'R-02': 'PDR', 'R-08': 'PDR', 'R-10': 'PDR', 'R-12': 'PDR', 'R-18': 'PDR',
|
|
194
196
|
'R-04': 'PDR', 'R-22': 'PDR', 'R-23': 'PDR',
|
|
195
197
|
'R-15': 'PDR',
|
|
@@ -199,13 +201,13 @@ export const RULE_TO_PHASE = {
|
|
|
199
201
|
'R-30': 'PDR', 'R-31': 'PDR',
|
|
200
202
|
'MT-01': 'PDR', 'MT-02': 'PDR',
|
|
201
203
|
'ND-01': '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.
|
|
204
|
+
'BW-02': 'PDR', 'CR-01': 'PDR', 'IO-01': 'PDR', 'IO-02': 'PDR', // CR-SM-226: extended to all FCHAIN FUNC-pairs, added to the phase axis.
|
|
203
205
|
// CDR — critical design/schema completeness.
|
|
204
206
|
'R-26': 'CDR', 'SC-02': 'CDR', // SC-04 entfiel mit CR-SM-271 — der FLOW-ohne-SCHEMA-Fall haengt an R-18/PDR
|
|
205
207
|
'ND-02': 'CDR',
|
|
206
208
|
'NFR-01': 'CDR',
|
|
207
209
|
// TRR — test readiness.
|
|
208
|
-
'R-01': 'TRR', 'R-05': 'TRR', 'R-19': 'TRR', 'R-20': 'TRR', 'R-21': 'TRR',
|
|
210
|
+
'R-01': 'TRR', 'R-05': 'TRR', 'R-32': 'TRR', 'R-19': 'TRR', 'R-20': 'TRR', 'R-21': 'TRR',
|
|
209
211
|
// CR-SM-231: eine doppelt beanspruchte Testdatei laesst den TRR-Gate dieselbe Evidenz
|
|
210
212
|
// doppelt zaehlen — der Befund gehoert genau an dieses Gate.
|
|
211
213
|
'R-29': 'TRR',
|
package/dist/se/rule-help.js
CHANGED
|
@@ -147,6 +147,10 @@ export const RULE_HELP = {
|
|
|
147
147
|
plain: "Two steps in the same sequence have no described data passing between them → add the data one hands to the other.",
|
|
148
148
|
se: "A `FUNC` pair inside one `FCHAIN` with no `io` path (`FUNC -io-> FLOW -io-> FUNC`) connecting them.",
|
|
149
149
|
},
|
|
150
|
+
'IO-02': {
|
|
151
|
+
plain: "Two different places write into the same flow, so a reader cannot tell which version arrives \u2192 give each source its own flow; they may keep sharing one contract.",
|
|
152
|
+
se: "`FLOW` with more than one producer (`FUNC`/`ACTOR -io-> FLOW`). R-10 checks the LOWER bound of the same axis (at least one producer, at least one consumer); the two can never fire on the same FLOW, so there is no double count. Only the producer side is bounded: several consumers are the normal shape of a shared contract \u2014 one source, many readers, which is exactly how a central configuration looks. One finding per FLOW, `value` = number of producers, `threshold` 1. Severity `error` (hygiene) and deliberately NOT in STEER_RULES — a decision, not a measured conflict: a split flow keeps its `SCHEMA`, so BW-02 (distinct contracts per boundary) does not rise. Whether a gate blocks a new finding is the consumer's gating choice, not part of the rule.",
|
|
153
|
+
},
|
|
150
154
|
'MS-01': {
|
|
151
155
|
plain: "A milestone has no work assigned to it → assign the work items that belong to it.",
|
|
152
156
|
se: "`MS` with no `CR` `relation`.",
|
|
@@ -190,13 +194,17 @@ export const RULE_HELP = {
|
|
|
190
194
|
se: "`FUNC` with no `satisfy` trace to a `REQ` (design→requirement traceability).",
|
|
191
195
|
},
|
|
192
196
|
'R-04': {
|
|
193
|
-
plain: "
|
|
194
|
-
se: "`MOD`
|
|
197
|
+
plain: "Too many different data formats cross this module's boundary → merge formats, or move the functions that carry them.",
|
|
198
|
+
se: "`MOD` whose boundary is crossed by `metricPolicy.boundaryWidth.warning` or more DISTINCT contracts (`SCHEMA` on the io path `FUNC` ─io→ `FLOW` ─io→ `FUNC` across the boundary, union over all neighbours — CR-SM-276). Same question and same threshold as BW-02 on the FUNC tree (CR-SM-312); module SIZE is RD-04's question since CR-SM-311.",
|
|
195
199
|
prompt: "se-view:arch",
|
|
196
200
|
},
|
|
197
201
|
'R-05': {
|
|
198
202
|
plain: "A test doesn't check any feature you promised → link it to the feature it tests, or remove it.",
|
|
199
|
-
se: "`TEST` with no `verify` trace (test→requirement coverage) to a `
|
|
203
|
+
se: "`TEST` with no `verify` trace at all — neither to a `REQ` (test→requirement coverage) nor to a `SCHEMA` (contract test, CR-SM-317).",
|
|
204
|
+
},
|
|
205
|
+
'R-32': {
|
|
206
|
+
plain: "A data contract exists in code but no test exercises it as a contract → add a test that tries every variant, including the ones it must reject, and link it to the schema.",
|
|
207
|
+
se: "`SCHEMA` with a symbol `realRef` (a Zod contract) and no `TEST -verify-> SCHEMA`. RC-04 checks the parse at the boundary; this checks the contract test (CR-SM-319).",
|
|
200
208
|
},
|
|
201
209
|
'R-08': {
|
|
202
210
|
plain: "A link points at something that no longer exists → repair or remove the broken link.",
|
|
@@ -235,8 +243,8 @@ export const RULE_HELP = {
|
|
|
235
243
|
se: "Realized `FUNC` with no valid `realRef` `{file, symbol}` (graph↔code binding); else `concept:true` / `external:true`.",
|
|
236
244
|
},
|
|
237
245
|
'R-21': {
|
|
238
|
-
plain: "
|
|
239
|
-
se: "FUNC↔FUNC
|
|
246
|
+
plain: "Two functions hand data over, but they are not in one chain together — or they are, and nothing tests the hand-off → put both into the same chain, and give that chain an integration test.",
|
|
247
|
+
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 carries a verified integration test (`TEST` ─verify→ `REQ` ←satisfy─ `FCHAIN`) → finding at the chain. 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.",
|
|
240
248
|
},
|
|
241
249
|
'R-22': {
|
|
242
250
|
plain: "A function isn't assigned to any building block, so it has no home in the structure → put it on a module.",
|
|
@@ -301,7 +309,11 @@ export const RULE_HELP = {
|
|
|
301
309
|
},
|
|
302
310
|
'RD-04': {
|
|
303
311
|
plain: "One thing has more than 9 parts directly under it → group them, so each level stays readable.",
|
|
304
|
-
se: "Decomposition breadth above `metricPolicy.decompositionBreadth.warning` children on one level — `FUNC` `compose` `FUNC`, `SYS
|
|
312
|
+
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.",
|
|
313
|
+
},
|
|
314
|
+
'RD-05': {
|
|
315
|
+
plain: "A level has only one or two parts under it → it groups nothing; fold it into the level above, or gather the parts that belong together under it.",
|
|
316
|
+
se: "Decomposition breadth below `metricPolicy.decompositionBreadth.min` (default 3, exclusive) on one level, counted exactly like RD-04 (CR-SM-311, Z3). A level abstracts nothing below it. The finding carries no `value`/`threshold` and does not enter the steering score: it is readability, not boundary width. A level with no children at all is not this rule (empty MOD: R-23; FUNC without children is a leaf).",
|
|
305
317
|
},
|
|
306
318
|
'SC-02': {
|
|
307
319
|
plain: "A data format is defined but nothing uses it → connect it to the data it describes, or drop it.",
|