@sigloch/contracts 10.0.0 → 10.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/se/conformance-rules.d.ts +12 -0
- package/dist/se/conformance-rules.js +6 -6
- package/dist/se/evaluate-all.d.ts +1 -1
- package/dist/se/evaluate-all.js +21 -0
- package/dist/se/grammar-snapshot.d.ts +4 -3
- package/dist/se/grammar-snapshot.js +84 -1
- package/dist/se/index.d.ts +3 -1
- package/dist/se/index.js +11 -1
- package/dist/se/readiness.d.ts +22 -0
- package/dist/se/readiness.js +22 -0
- package/dist/se/rule-help.d.ts +52 -0
- package/dist/se/rule-help.js +342 -0
- package/package.json +3 -2
|
@@ -57,6 +57,18 @@ export interface ConformanceRuleDefinition {
|
|
|
57
57
|
id: string;
|
|
58
58
|
name: string;
|
|
59
59
|
severity: RuleSeverity;
|
|
60
|
+
/**
|
|
61
|
+
* CR-SM-305: die Grundgesamtheit, ueber die die Regel meldet — dieselbe Bedeutung wie an
|
|
62
|
+
* jeder Katalogregel (CR-SM-235), damit RC in `ALL_RULE_DEFS` stehen kann, ohne dass ein
|
|
63
|
+
* Feld erfunden werden muss.
|
|
64
|
+
*
|
|
65
|
+
* GEMESSEN, nicht gesetzt: RC-01 meldet 10x an FUNC, RC-04 4x an SCHEMA, RC-05 5x an MOD
|
|
66
|
+
* ueber fuenf Familien-Repos; RC-02/RC-03 sind dort still und ihr Typ ist aus der Schleife
|
|
67
|
+
* gelesen (`el.type !== 'TEST'` / `'SCHEMA'`). RC-06 laeuft ueber jedes Element mit
|
|
68
|
+
* `external` + `realRef`, und genau drei Typen duerfen diese Attribute tragen
|
|
69
|
+
* (`ELEMENT_ATTRIBUTES`): FUNC, MOD, SCHEMA.
|
|
70
|
+
*/
|
|
71
|
+
domain: readonly string[];
|
|
60
72
|
evaluate: (graph: OntologyGraph, facts: CodeFacts) => RuleViolation[];
|
|
61
73
|
}
|
|
62
74
|
/**
|
|
@@ -450,12 +450,12 @@ function externalRefMustNameDependency(graph, facts) {
|
|
|
450
450
|
}
|
|
451
451
|
/** All RC conformance rules — evaluated by executors that can supply CodeFacts. */
|
|
452
452
|
export const CODE_CONFORMANCE_RULES = [
|
|
453
|
-
{ id: 'RC-01', name: 'FUNC realRef resolves to a declared symbol', severity: 'error', evaluate: codeRefMustResolve },
|
|
454
|
-
{ id: 'RC-02', name: 'testRefs entries resolve to runnable tests', severity: 'error', evaluate: testRefMustResolve },
|
|
455
|
-
{ id: 'RC-03', name: 'SCHEMA realRef resolves to a declared export', severity: 'error', evaluate: schemaRefMustResolve },
|
|
456
|
-
{ id: 'RC-04', name: 'SCHEMA realRef is parsed at its interface', severity: 'warning', evaluate: schemaRefMustBeUsed },
|
|
457
|
-
{ id: 'RC-05', name: 'cross-module import drift', severity: 'warning', evaluate: importDriftConformance },
|
|
458
|
-
{ id: 'RC-06', name: 'external realRef names a declared dependency', severity: 'warning', evaluate: externalRefMustNameDependency },
|
|
453
|
+
{ id: 'RC-01', name: 'FUNC realRef resolves to a declared symbol', severity: 'error', domain: ['FUNC'], evaluate: codeRefMustResolve },
|
|
454
|
+
{ id: 'RC-02', name: 'testRefs entries resolve to runnable tests', severity: 'error', domain: ['TEST'], evaluate: testRefMustResolve },
|
|
455
|
+
{ id: 'RC-03', name: 'SCHEMA realRef resolves to a declared export', severity: 'error', domain: ['SCHEMA'], evaluate: schemaRefMustResolve },
|
|
456
|
+
{ id: 'RC-04', name: 'SCHEMA realRef is parsed at its interface', severity: 'warning', domain: ['SCHEMA'], evaluate: schemaRefMustBeUsed },
|
|
457
|
+
{ id: 'RC-05', name: 'cross-module import drift', severity: 'warning', domain: ['MOD'], evaluate: importDriftConformance },
|
|
458
|
+
{ id: 'RC-06', name: 'external realRef names a declared dependency', severity: 'warning', domain: ['FUNC', 'MOD', 'SCHEMA'], evaluate: externalRefMustNameDependency },
|
|
459
459
|
];
|
|
460
460
|
/** Run all RC rules against a graph + extracted code facts. */
|
|
461
461
|
export function evaluateConformanceRules(graph, facts) {
|
|
@@ -14,7 +14,7 @@ import type { MetricPolicy } from './policy.js';
|
|
|
14
14
|
* wenn es keine zweite gibt.
|
|
15
15
|
*/
|
|
16
16
|
/** Profile groupings — see CATALOGS. */
|
|
17
|
-
export type ProfileId = 'default' | 'se' | 'coding';
|
|
17
|
+
export type ProfileId = 'default' | 'se' | 'coding' | 'conformance';
|
|
18
18
|
export declare const ALL_RULE_DEFS: ReadonlyArray<{
|
|
19
19
|
id: string;
|
|
20
20
|
name: string;
|
package/dist/se/evaluate-all.js
CHANGED
|
@@ -11,6 +11,7 @@ import { ND_RULES, evaluateNDRules } from './near-duplicate-rules.js';
|
|
|
11
11
|
import { AO_RULES, evaluateAORules } from './ao-rules.js';
|
|
12
12
|
import { BQ_RULES, evaluateBQRules } from './quality-rules.js';
|
|
13
13
|
import { AF_RULES, evaluateAFRules } from './analysis-freshness-rules.js';
|
|
14
|
+
import { CODE_CONFORMANCE_RULES } from './conformance-rules.js';
|
|
14
15
|
/**
|
|
15
16
|
* CR-SM-285: das Profil haengt am KATALOG, nicht am ID-Praefix.
|
|
16
17
|
*
|
|
@@ -38,6 +39,26 @@ const CATALOGS = [
|
|
|
38
39
|
// Sprach-/Textqualitaet statt SE-Struktur — das ist die Trennlinie, die die Praefixliste meinte.
|
|
39
40
|
{ profile: 'coding', rules: BQ_RULES },
|
|
40
41
|
{ profile: 'coding', rules: ND_RULES },
|
|
42
|
+
/*
|
|
43
|
+
* CR-SM-305: die RC-Regeln stehen im Katalog — mit EIGENEM Profil, weil sie eine andere
|
|
44
|
+
* Signatur haben: `(graph, facts: CodeFacts)` statt `(graph, policy)`.
|
|
45
|
+
*
|
|
46
|
+
* Warum ueberhaupt: das Kongruenz-Urteil existierte, war getestet und erreichte KEINEN
|
|
47
|
+
* Produktionspfad. Gate (`harness.mutate`), Steuerung (fit-advisory, steering-snapshot) und
|
|
48
|
+
* `GET /api/graph/readiness` lesen alle `ALL_RULE_DEFS`; RC stand nicht darin, also ging jeder
|
|
49
|
+
* Modell-Zug, der die Bindung an den Code bricht, lautlos durch. Der einzige Aufrufer von
|
|
50
|
+
* `scoreReadinessWithConformance` war ein Test.
|
|
51
|
+
*
|
|
52
|
+
* Warum ein eigenes Profil und nicht `se`: das Profil traegt seit CR-SM-285 die
|
|
53
|
+
* AUSWERTBARKEIT mit. Stuende RC unter `se`, behauptete `getRuleDefsForProfile('se')` eine
|
|
54
|
+
* Auswertung, die ohne Repo-Wurzel gar nicht stattfinden kann.
|
|
55
|
+
*
|
|
56
|
+
* `evaluateAllRules` fuehrt sie NICHT aus — es kann es nicht, es hat keine `CodeFacts`. Genau
|
|
57
|
+
* diese Differenz ist das Signal: deklariert und nicht ausgewertet heisst NICHT GEPRUEFT, und
|
|
58
|
+
* die vorhandene Ableitung `ALL_RULE_DEFS minus ausgewertet` macht es von selbst laut. Kein
|
|
59
|
+
* zweiter Zweig — die ND-fail-open-Lehre aus CR-SM-286.
|
|
60
|
+
*/
|
|
61
|
+
{ profile: 'conformance', rules: CODE_CONFORMANCE_RULES },
|
|
41
62
|
];
|
|
42
63
|
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 })));
|
|
43
64
|
export function getRuleDefsForProfile(profile) {
|
|
@@ -13,15 +13,16 @@ export declare const GRAMMAR_SNAPSHOT: {
|
|
|
13
13
|
readonly versions: {
|
|
14
14
|
readonly ontology: "9.0.0";
|
|
15
15
|
readonly metaModel: "5.0.0";
|
|
16
|
-
readonly rules: "19.
|
|
16
|
+
readonly rules: "19.2.0";
|
|
17
17
|
};
|
|
18
18
|
readonly elementTypes: readonly ["ACTOR", "CR", "FCHAIN", "FLOW", "FUNC", "MOD", "MS", "REQ", "SCHEMA", "SYS", "TEST", "UC"];
|
|
19
19
|
readonly traceTypes: readonly ["allocate", "compose", "io", "relation", "satisfy", "verify"];
|
|
20
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
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"];
|
|
22
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"];
|
|
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
|
+
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]", "RC-01 (error) domain=[FUNC]", "RC-02 (error) domain=[TEST]", "RC-03 (error) domain=[SCHEMA]", "RC-04 (warning) domain=[SCHEMA]", "RC-05 (warning) domain=[MOD]", "RC-06 (warning) domain=[FUNC,MOD,SCHEMA]", "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]"];
|
|
24
24
|
readonly conformanceRules: readonly ["RC-01 (error)", "RC-02 (error)", "RC-03 (error)", "RC-04 (warning)", "RC-05 (warning)", "RC-06 (warning)"];
|
|
25
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
|
|
26
|
+
readonly ruleHelp: readonly ["AF-01", "AF-02", "AF-03", "AF-04", "AF-05", "BQ-01", "BQ-02", "BQ-04", "BQ-06", "BQ-07", "BW-02", "CL-01", "CR-01", "CR-R01", "CR-R02", "CR-R03", "FC-02", "FC-03", "FC-04", "FM-01", "FM-02", "FM-03", "IO-01", "MS-01", "MS-02", "MS-03", "MT-01", "MT-02", "ND-01", "ND-02", "NFR-01", "R-01", "R-02", "R-04", "R-05", "R-08", "R-10", "R-12", "R-15", "R-16", "R-17", "R-18", "R-19", "R-20", "R-21", "R-22", "R-23", "R-26", "R-29", "R-30", "R-31", "RC-01", "RC-02", "RC-03", "RC-04", "RC-05", "RC-06", "RD-01", "RD-02", "RD-03", "RD-04", "SC-02", "UC-01", "UC-02", "UC-03", "UC-04", "UC-05", "UC-06", "VR-01"];
|
|
27
|
+
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", "READINESS_SCORED_PROFILES", "REQUIRED_PATTERNS", "RULES_VERSION", "RULE_HELP", "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", "crossingContractCount", "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", "moduleCrossings", "moduleMetrics", "mt01Instability", "mt02Lcom4", "nd01FuncNearDuplicate", "nd02SchemaNearDuplicate", "nfr01BudgetOvershoot", "normalizeReqKinds", "pairsAbove", "parseElementUid", "parseFormatE", "sc02IsReferenced", "schemaSimilarity", "serializeToFormatE", "setBQ04SimilarityMatrix", "subtreeFuncs", "toElementUid", "toEvaluableGraph", "tokens", "traceRejection", "tryParseElementUid", "uc01HasRequirements", "uc02HasActor", "uc03HasScenario", "uc04GoalDefined", "uc05HasPostcondition", "uc06HasPrecondition", "vr01TestNoResult", "whiteboxContractCount"];
|
|
27
28
|
};
|
|
@@ -13,7 +13,7 @@ export const GRAMMAR_SNAPSHOT = {
|
|
|
13
13
|
versions: {
|
|
14
14
|
ontology: "9.0.0",
|
|
15
15
|
metaModel: "5.0.0",
|
|
16
|
-
rules: "19.
|
|
16
|
+
rules: "19.2.0",
|
|
17
17
|
},
|
|
18
18
|
elementTypes: [
|
|
19
19
|
"ACTOR",
|
|
@@ -171,6 +171,12 @@ export const GRAMMAR_SNAPSHOT = {
|
|
|
171
171
|
"R-29 (error) domain=[TEST]",
|
|
172
172
|
"R-30 (warning) domain=[FUNC]",
|
|
173
173
|
"R-31 (warning) domain=[FUNC]",
|
|
174
|
+
"RC-01 (error) domain=[FUNC]",
|
|
175
|
+
"RC-02 (error) domain=[TEST]",
|
|
176
|
+
"RC-03 (error) domain=[SCHEMA]",
|
|
177
|
+
"RC-04 (warning) domain=[SCHEMA]",
|
|
178
|
+
"RC-05 (warning) domain=[MOD]",
|
|
179
|
+
"RC-06 (warning) domain=[FUNC,MOD,SCHEMA]",
|
|
174
180
|
"RD-01 (warning) domain=[REQ]",
|
|
175
181
|
"RD-02 (warning) domain=[REQ]",
|
|
176
182
|
"RD-03 (info) domain=[REQ]",
|
|
@@ -202,6 +208,77 @@ export const GRAMMAR_SNAPSHOT = {
|
|
|
202
208
|
"moduleSize = {coupled:7,crossings:2,large:9}",
|
|
203
209
|
"riskRpn = 100",
|
|
204
210
|
],
|
|
211
|
+
ruleHelp: [
|
|
212
|
+
"AF-01",
|
|
213
|
+
"AF-02",
|
|
214
|
+
"AF-03",
|
|
215
|
+
"AF-04",
|
|
216
|
+
"AF-05",
|
|
217
|
+
"BQ-01",
|
|
218
|
+
"BQ-02",
|
|
219
|
+
"BQ-04",
|
|
220
|
+
"BQ-06",
|
|
221
|
+
"BQ-07",
|
|
222
|
+
"BW-02",
|
|
223
|
+
"CL-01",
|
|
224
|
+
"CR-01",
|
|
225
|
+
"CR-R01",
|
|
226
|
+
"CR-R02",
|
|
227
|
+
"CR-R03",
|
|
228
|
+
"FC-02",
|
|
229
|
+
"FC-03",
|
|
230
|
+
"FC-04",
|
|
231
|
+
"FM-01",
|
|
232
|
+
"FM-02",
|
|
233
|
+
"FM-03",
|
|
234
|
+
"IO-01",
|
|
235
|
+
"MS-01",
|
|
236
|
+
"MS-02",
|
|
237
|
+
"MS-03",
|
|
238
|
+
"MT-01",
|
|
239
|
+
"MT-02",
|
|
240
|
+
"ND-01",
|
|
241
|
+
"ND-02",
|
|
242
|
+
"NFR-01",
|
|
243
|
+
"R-01",
|
|
244
|
+
"R-02",
|
|
245
|
+
"R-04",
|
|
246
|
+
"R-05",
|
|
247
|
+
"R-08",
|
|
248
|
+
"R-10",
|
|
249
|
+
"R-12",
|
|
250
|
+
"R-15",
|
|
251
|
+
"R-16",
|
|
252
|
+
"R-17",
|
|
253
|
+
"R-18",
|
|
254
|
+
"R-19",
|
|
255
|
+
"R-20",
|
|
256
|
+
"R-21",
|
|
257
|
+
"R-22",
|
|
258
|
+
"R-23",
|
|
259
|
+
"R-26",
|
|
260
|
+
"R-29",
|
|
261
|
+
"R-30",
|
|
262
|
+
"R-31",
|
|
263
|
+
"RC-01",
|
|
264
|
+
"RC-02",
|
|
265
|
+
"RC-03",
|
|
266
|
+
"RC-04",
|
|
267
|
+
"RC-05",
|
|
268
|
+
"RC-06",
|
|
269
|
+
"RD-01",
|
|
270
|
+
"RD-02",
|
|
271
|
+
"RD-03",
|
|
272
|
+
"RD-04",
|
|
273
|
+
"SC-02",
|
|
274
|
+
"UC-01",
|
|
275
|
+
"UC-02",
|
|
276
|
+
"UC-03",
|
|
277
|
+
"UC-04",
|
|
278
|
+
"UC-05",
|
|
279
|
+
"UC-06",
|
|
280
|
+
"VR-01",
|
|
281
|
+
],
|
|
205
282
|
exports: [
|
|
206
283
|
"AF_RULES",
|
|
207
284
|
"ALL_RULE_DEFS",
|
|
@@ -237,8 +314,10 @@ export const GRAMMAR_SNAPSHOT = {
|
|
|
237
314
|
"OntologyGraph",
|
|
238
315
|
"PHASE_READINESS_NAME",
|
|
239
316
|
"PhaseGate",
|
|
317
|
+
"READINESS_SCORED_PROFILES",
|
|
240
318
|
"REQUIRED_PATTERNS",
|
|
241
319
|
"RULES_VERSION",
|
|
320
|
+
"RULE_HELP",
|
|
242
321
|
"RULE_TO_DIMENSION",
|
|
243
322
|
"RULE_TO_PHASE",
|
|
244
323
|
"ReadinessDimension",
|
|
@@ -274,6 +353,7 @@ export const GRAMMAR_SNAPSHOT = {
|
|
|
274
353
|
"bw02WhiteboxWidth",
|
|
275
354
|
"cl01ConopsCompleteness",
|
|
276
355
|
"cr01CrossingFlowCount",
|
|
356
|
+
"crossingContractCount",
|
|
277
357
|
"decomposedFuncs",
|
|
278
358
|
"evaluateAFRules",
|
|
279
359
|
"evaluateAORules",
|
|
@@ -307,6 +387,7 @@ export const GRAMMAR_SNAPSHOT = {
|
|
|
307
387
|
"jaccard",
|
|
308
388
|
"maxOccurs",
|
|
309
389
|
"minOccurs",
|
|
390
|
+
"moduleCrossings",
|
|
310
391
|
"moduleMetrics",
|
|
311
392
|
"mt01Instability",
|
|
312
393
|
"mt02Lcom4",
|
|
@@ -321,6 +402,7 @@ export const GRAMMAR_SNAPSHOT = {
|
|
|
321
402
|
"schemaSimilarity",
|
|
322
403
|
"serializeToFormatE",
|
|
323
404
|
"setBQ04SimilarityMatrix",
|
|
405
|
+
"subtreeFuncs",
|
|
324
406
|
"toElementUid",
|
|
325
407
|
"toEvaluableGraph",
|
|
326
408
|
"tokens",
|
|
@@ -333,5 +415,6 @@ export const GRAMMAR_SNAPSHOT = {
|
|
|
333
415
|
"uc05HasPostcondition",
|
|
334
416
|
"uc06HasPrecondition",
|
|
335
417
|
"vr01TestNoResult",
|
|
418
|
+
"whiteboxContractCount",
|
|
336
419
|
],
|
|
337
420
|
};
|
package/dist/se/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
/** Ontology schema version (element types + trace types). */
|
|
6
6
|
export declare const ONTOLOGY_VERSION = "9.0.0";
|
|
7
7
|
/** Rules engine version (validation rules incl. RC conformance). */
|
|
8
|
-
export declare const RULES_VERSION = "19.
|
|
8
|
+
export declare const RULES_VERSION = "19.2.0";
|
|
9
9
|
/** Meta-model version (trace pattern constraints + format-e parser). */
|
|
10
10
|
export declare const META_MODEL_VERSION = "5.0.0";
|
|
11
11
|
export * from './ontology.js';
|
|
@@ -23,6 +23,8 @@ export * from './cr-quality-rules.js';
|
|
|
23
23
|
export * from './near-duplicate-rules.js';
|
|
24
24
|
export * from './similarity.js';
|
|
25
25
|
export * from './ao-rules.js';
|
|
26
|
+
export * from './rule-help.js';
|
|
27
|
+
export * from './module-crossings.js';
|
|
26
28
|
export * from './quality-rules.js';
|
|
27
29
|
export * from './analysis-freshness-rules.js';
|
|
28
30
|
export * from './evaluate-all.js';
|
package/dist/se/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
/** Ontology schema version (element types + trace types). */
|
|
6
6
|
export const ONTOLOGY_VERSION = '9.0.0'; // BREAKING (CR-SM-294): das Feld `asil` entfaellt ersatzlos, zusammen mit dem Enum `AsilLevel`. Sein einziger Leser war R-03 (ASIL isolation), und die Messung ueber 19 Familiengraphen (4540 Elemente) zeigt: 0 von 305 MOD tragen `asil` ueberhaupt. Ein Feld ohne Schreiber ist eine Regel, die nie feuert -- Gate 3 der Grammatik-Review. Mit R-03 fallen im selben Zug RT-01, PH-01, R-27 (alle drei lesen `attributes.kind === 'physical'`, 0 von 305 MOD tragen es) und CA-01 (`attributes.requires` / `attributes.capability`, 0/0). Die physische Ebene der Ontologie war nie in Gebrauch: kein Mitglied der Familie modelliert Hardware oder funktionale Sicherheit. `kind`, `requires` und `capability` brauchen KEINEN Schema-Eingriff -- sie lagen im freien `attributes`-Sack und sind nach der Streichung ihrer Leser schlicht unbenutzte Schluessel. Migration: ein Graph, der `asil` traegt, verliert das Feld beim naechsten Reseed; kein Element und keine Kante faellt (0 -> 0 Befunde ueber alle 19 Graphen). Prior: BREAKING (CR-SM-266a): drei Enums schrumpfen, und alle drei sind ENTFERNUNGEN. (1) ElementType 13 -> 12: `SESSION` entfaellt. (2) TraceType 7 -> 6: `produces` entfaellt. Beide trugen genau EIN Pattern (`SESSION -produces-> *`), und die Messung hat es widerlegt: 0 produces-Kanten und 0 SESSION-Knoten in ALLEN 9 aktiven Familie-Graphen, auch im graphcode-Selbstmodell nach 195 gegateten Versionen. Die reale Provenance lebt seit CR-GC-347 in `.graphcode/audit.jsonl` -- audit_trail/audit_stats lesen die DATEI, nie den Graphen; einziger Schreiber war ein toter Pfad (CR-195d in graph-api-core), Leser mit Wirkung keiner. Der urspruengliche CR-Entwurf hielt das Pattern fuer die Provenance-Kante und wollte es BEHALTEN ('Nicht-Befund'); die Zaehlung hat den Nicht-Befund kassiert -- Gate 1 verlangt fuer das Wiederaufmachen einer Entscheidung eine Messung, und hier war sie es. (3) Mit `produces` faellt `TraceCategory` und `Trace.category`. Das ist die wichtigste Haelfte: R-08 und R-18 haben `category === 'audit'` UEBERSPRUNGEN, also haette nach D5 jede Kante mit diesem selbstgesetzten Attribut die komplette Pattern-Matrix UND die Referenzintegritaet umgangen. Ein Attribut, das eine Strukturpruefung abschaltet, ist die Klasse aus CR-SM-263/-257; hier zusaetzlich der billige Zweitweg aus CR-GC-366, nur ohne Kante. Gemessen: 0 von 0 Traces aller 9 Graphen tragen `category` -- die Entfernung nimmt niemandem etwas weg. (4) ReqKind 7 -> 6: `negative` entfaellt. Ein Verbots-REQ ist auch eine Anforderung -- die Implementierung muss Regeln abfragen oder Sicherungen einbauen, das ist `functional`. Der Wert hatte NULL Leser (anders als risk/mitigation -> FM-01..03, pre/postcondition -> UC-05/06, non-functional -> NFR-01) und haette durch die neuen where-Praedikate per AUSLASSUNG erstmals Wirkung bekommen: er stand in keiner der vier Listen und waere nur noch per FCHAIN erfuellbar gewesen. Die sechs verbleibenden Werte partitionieren die where-Listen VOLLSTAENDIG. Migration `negative`: 3 REQs, alle graphcode, Ziel-kind je REQ statt pauschal -- REQ-dashboard-readonly und REQ-readonly-bridge nach `non-functional` (Architektur-Constraint an der Modulgrenze, konsistent mit D2), REQ-no-extraction nach `functional`. Rest-Reject dabei: genau 1 (`FUNC-serve-sse -satisfy-> REQ-readonly-bridge`), aufzuloesen durch Loeschen oder Heben auf die FCHAIN. Prior: BREAKING (CR-GC-366): das Trace-Pattern `FUNC -satisfy-> UC` entfaellt ersatzlos. Es war ein zweiter Weg vom Verhalten zum Use Case neben dem einzig tragenden `UC -compose-> FCHAIN -compose-> FUNC` — und der billigere: eine FUNC konnte einen UC bedienen, ohne in dessen Wirkkette zu stehen, womit IO-01 (FLOW-Pfade je Kettenpaar) und R-21 (Integrationstest je Kette) sie nie sahen. Die Abkuerzung umging genau die Pruefungen, die die Anbindung belastbar machen. Am graphcode-Selbstmodell waren 10 der 26 solchen Kanten reine Dopplung (die FUNC stand ohnehin in der FCHAIN), die restlichen 13 sind der Migrationsanlass. Jeder Graph mit solchen Kanten faellt jetzt R-18 (error) zur Last und muss migriert werden: FUNC in die FCHAIN des UC aufnehmen, satisfy-Kante loeschen. Prior: BREAKING (CR-SM-231b): das knotenweite `testResult` entfaellt — das Ergebnis haengt PRO `testRefs`-Eintrag (`result`, `ranAt`, `evidence`), aus demselben Grund wie `tool`. Ein einzelnes Ergebnis am Knoten konnte bei n Laeufen nicht sagen, welcher gemeint ist, und "einer rot, einer gruen" war gar nicht darstellbar — genau der Zustand, den ein Gate wissen muss. FM-03 liest jetzt "jeder Eintrag passed": "irgendeiner gruen" haette einen gruenen Unit-Lauf einen roten Visual-Lauf verdecken lassen. Ein Eintrag ohne Ergebnis ist nicht bestanden. VR-01 meldet die Dateien ohne Ergebnis statt nur den Knoten. Prior: BREAKING (CR-SM-231): `testRef` (Objekt) entfaellt ersatzlos zugunsten von `testRefs` (Array, min 1) — eine Abnahme, n Testdateien. Kein Union, kein Alias: ein Graph mit dem alten Attribut faellt R-19 zur Last und muss migriert werden. Anlass war ein Zaehl-Audit (537 laufende Tests in 67 Dateien, 14 TEST-Knoten mit je genau einer Datei, 53 Dateien an keine Abnahme gebunden) plus ein belegter Ausweichweg: dieselbe Spec-Datei stand im testRef ZWEIER TEST-Knoten, womit die Relation faktisch n:m war — ein roter Lauf keiner Abnahme mehr eindeutig zuordenbar, der TRR-Gate zaehlte dieselbe Evidenz doppelt. `tool` bleibt PRO EINTRAG: eine Abnahme mischt real die Runner (vitest + playwright). +AttributeSpec.type 'array' (testRefs ist das erste Listen-Attribut). Prior: BREAKING: `SemanticId` (`Name.TypeAbbr.Counter`) deleted, `ElementUid` (`<TYPE>-<slug>`) is the family canon — the old canon was used by no production graph of the family while 626 of 1145 elements already carried TYPE-slug (CR-SM-217); realRef unifies codeRef+schemaRef (+physical-MOD CAD ref), symbol optional; testRef stays separate (CR-228 C); +RepoRelativePathSchema on testRef/realRef .file — no absolute/`..` paths (CR-GC-255)
|
|
7
7
|
/** Rules engine version (validation rules incl. RC conformance). */
|
|
8
|
-
export const RULES_VERSION = '19.0.0'; // BREAKING (CR-SM-293): MT-01 zaehlt KOPPLUNG statt aller Kanten, dreht die Richtung um und urteilt per Default nicht mehr. (1) fan_in/fan_out lasen bis hierher JEDE Kante, deren eines Ende einem Modul gehoerte. Gemessen ueber 19 Familiengraphen: von 3281 gezaehlten Kanten sind nur 1117 (34 %) Kopplung. fan_in 2164 = 674 `allocate` -- das ist die MODULGROESSE, ein Modul wurde also stabiler, indem es Funktionen bekam -- plus 610 `FLOW -io-> FUNC`, 348 `FCHAIN -compose-> FUNC`, 255 `CR -relation-> FUNC`, 277 Rest. fan_out 1117 = 507 `FUNC -io-> FLOW` plus 501 `FUNC -satisfy-> REQ`; fast die halbe fan_out war SPEZIFIKATION, dieselbe Begruendung, mit der CR-SM-297 `satisfy` aus LCOM4 genommen hat. Dazu 70 Kanten ueber `MOD -io-> MOD`, ein Muster, das CR-SM-266 D2 aus TRACE_PATTERNS geloescht hat. MT-01 liest jetzt `moduleCrossings` -- DIESELBE Definition von Rand und dieselbe Zaehlbasis (verschiedene Vertraege), die CR-01, R-04 und BW-02 seit CR-SM-274/276 benutzen; MT-01 hatte bis hierher noch eine dritte. (2) RICHTUNG: der KONSUMENT haengt ab. Wer nach draussen liefert, wird gebraucht (afferent, fan_in); wer von draussen bezieht, haengt ab (efferent, fan_out). Das ist Martins Ca/Ce; die alte Lesart 'Kante zeigt weg = Abhaengigkeit' drehte jedes reine Verbrauchermodul auf I = 0 (maximal stabil), wo es 1 sein muss. Die Konvention stand vorher NIRGENDS im Repo -- sie war nie entschieden, nur codiert. (3) `DEFAULT_METRIC_POLICY.instability` 0.7 -> null, messen statt urteilen. Die Verteilung ist zweigipflig -- 44 von 149 messbaren Modulen exakt auf 0.00, 45 exakt auf 1.00, und 45 der 51 Befunde bei 0.7 sind genau diese 1.00 -- aus ihr laesst sich keine Schwelle ABLESEN (Praezedenz CR-SM-283/BW-02). Tiefer: I ist eine KOORDINATE, kein Defekt; Martins Satz lautet 'in Richtung Stabilitaet abhaengen', nicht 'I klein halten'. Damit fehlt MT-01 die Eigenschaft, die CR-SM-287 §2 von einer Steuerdimension verlangt (gerichtet, 'weniger ist besser, ohne Diskussion'), und (4) `STEER_RULES` schrumpft auf VIER. Praktisch war die Dimension ohnehin still: `steerScore` liest Verstoesse, und graphcodes Config setzt `instability: null` seit CR-GC-329 -- auf dem einzigen Repo, das taeglich steuert, lief der R5 laengst als R4. Der Nachfolger ist gemessen und angelegt (CR-SM-298): Martins Stable Dependencies Principle als gerichtete Groesse, Abhaengigkeiten 'bergauf' je Modul -- 34 von 305 (11 %), 132 von 146 Modulen bei null, Schwanz bis 6; lokal, gerichtet, budgetierbar, nicht entartet. Die Zahl `instability` bleibt vollstaendig erhalten: graph_metrics, Export und das gve-Dashboard rendern sie weiter, letzteres samt Hinweis 'Instabilitaet wird hier nur gemessen'. Prior: BREAKING (CR-SM-297, Teil 1): `satisfy` faellt aus der LCOM4-Verbindung von MT-02. Die Regel misst KOHAESION, und Kohaesion ist Datenkopplung -- geteilte `io`-Ziele und geteilte FLOW. `satisfy` ist dagegen eine SPEZIFIKATIONS-Beziehung: zwei FUNCs, die dasselbe REQ erfuellen, koennen zur Laufzeit vollstaendig entkoppelt sein. Die Wirkung ging dabei nur in EINE Richtung -- `satisfy` verbindet Gruppen, senkte also LCOM4 und liess Module kohaesiver aussehen, als ihr Datenfluss hergibt. Der Modellierungsgrund wiegt schwerer als der Messgrund: teilen sich zwei Funktionen ein Requirement, ist das REQUIREMENT zu zerlegen, nicht die Kohaesionsmessung zu beschoenigen; RD-02 sagt bereits das Verwandte. Gemessen ueber 19 Familiengraphen: MT-02 23 -> 24 Befunde. `satisfy` hat also fast nie zwei Gruppen verbunden -- die Aenderung ist prinzipiell richtig und praktisch billig. Golden neu verankert OHNE Zahlenaenderung: Totals und Reihenfolge bleiben an allen drei Eingaengen gleich (ssot 99, n700 1475, n3500 17495), nur die MT-02-shas wandern, weil die Meldung den gemessenen LCOM4-Wert woertlich nennt. NOCH OFFEN aus CR-SM-297: die beiden Container-Masse fuer den zerlegten FUNC (Kohaesion analog MT-02, Paar-Kopplung analog CR-01) -- ihre Schwellen sind aus der Verteilung ABZULESEN, nicht zu setzen (Praezedenz CR-SM-283/BW-02). Prior: BREAKING (CR-SM-296): je Frage eine Regel, je Schwelle ein Wert. (1) RD-04 gibt das Bein `FUNC -allocate-> MOD` an R-04 ab. Es zaehlte die allozierten FUNCs je Modul -- also die MODULGROESSE, und die misst R-04 auch. Beide feuerten am selben Modul im selben Batch, mit zwei Schwellen aus zwei Policy-Feldern (RD-04 > 11 gegen R-04 > 12), und welche recht hat, stand nirgends; dieselbe Ursache ging doppelt in den readiness-Nenner. R-04 ist die reichere Aussage -- Groesse GEGEN Kreuzungen, drei Urteile -- und liest ueber moduleCrossings ohnehin dieselben Daten. RD-04 bleibt fuer ZERLEGUNGSBREITE zustaendig: FUNC compose FUNC, SYS/MOD compose MOD und der FUNC-Wurzelwald am SYS (CR-SM-282). (2) Beide Schwellen sind an die Doktrin 7+-2 gebunden statt danebengesetzt: decompositionBreadth.warning 11 -> 9 (die Obergrenze der Doktrin) und moduleSize large 12 -> 9, coupled 8 -> 7. CR-SM-282 hatte gegen die Doktrin-Zahl 5 entschieden, weil `info` bei 5 den readiness-Nenner verwaessert haette -- das Argument traegt fuer die OBERgrenze nicht, denn RD-04 meldet als warning. Wirkung ueber 19 Familiengraphen, gemessen: RD-04 17 -> 15, R-04 9 -> 11, Summe 26 -> 26. Die Zahl bleibt, die Zustaendigkeit wird eindeutig. Prior: BREAKING (CR-SM-295): drei Regeln entfallen, eine wird neu gefasst -- Katalog 66 -> 63. (1) R-14 (UC must have compose) kann NIE ALLEIN feuern: sie prueft nur, ob ein UC irgendeine ausgehende compose-Kante hat, ohne den Zieltyp anzusehen, waehrend UC-01 den REQ und UC-03 die FCHAIN einzeln verlangen. Auf ELEMENTEBENE ueber 19 Familiengraphen gemessen, nicht auf Summen: R-14 (2 Befunde) ist eine echte Teilmenge von UC-01 vereinigt UC-03 (23 Befunde). Ihr Fixhinweis ('Add FCHAIN or REQ') versprach zudem eine Pruefung, die der Code nicht macht. (2) FC-01 (FCHAIN has actor boundary) ist von FC-04 gedeckt -- gemessen FC-01 (5) Teilmenge von FC-04 (27); FC-04 verlangt Eingang UND Ausgang, FC-01 nur eine Beruehrung. Dazu trug FC-01 einen TOTEN Ersatzweg: `hasDirectActorIO` prueft, ob der Eltern-UC actor-adjazent ist, und `ACTOR -io-> UC` hat CR-SM-266 (D1/D4) aus TRACE_PATTERNS entfernt -- der Zweig konnte seit drei Versionen nicht mehr wahr werden. (3) CR-R04 entfaellt und CR-R01 wird NEU GEFASST. Beide zielten daneben: CR-R01 akzeptierte jede relation-Kante, also auch einen CR, der nur an einem Meilenstein haengt (Termin, kein Umfang) -- 5 Befunde bei 49 CRs, die ausschliesslich auf ein MS zeigen. CR-R04 verlangte einen FUNC und war damit zu eng: 21 Befunde, darunter Daten-, Doku- und Konfigurationsaenderungen, die zu Recht keine Funktion beruehren. Die neue Fassung fragt nach dem UMFANG: mindestens eine relation auf FUNC, MOD, SCHEMA, REQ oder UC. Grundgesamtheit woertlich die von CR-R04 (CR-SM-255, nur offene CRs) -- an einem geschlossenen CR ist die Frage Archaeologie. Gemessen an 514 CR-Knoten: 54 ohne Umfangsbezug, davon 0 OFFEN, 52 done, 2 ohne Status. Die Verschaerfung laesst die Historie damit unangetastet und wirkt ab dem naechsten CR. MS-03 (CR ohne MS) bleibt unberuehrt -- sie stellt die komplementaere Frage. (4) R-17 behaelt ihre Pruefung und verliert ihren falschen Fixhinweis, der drei Zieltypen nannte, die sie nie angesehen hat. Prior: BREAKING (CR-SM-294): sechs Regeln entfallen ersatzlos, Katalog 72 -> 66. AO-D01 (RelayNodeDetection) ist STRUKTURELL unmoeglich -- sie verlangt `>= 2` ausgehende `io`-Kanten auf andere FUNC, und `FUNC -io-> FUNC` steht nicht in TRACE_PATTERNS; R-18 lehnt es als error ab. Das ist zeichengleich der Fall, fuer den CR-SM-283 AO-D03 geloescht hat -- AO-D03 fiel, AO-D01 blieb stehen. CA-01, RT-01, PH-01, R-27 und R-03 sind GEGENSTANDSLOS: sie lesen `asil`, `attributes.kind === 'physical'`, `attributes.requires` und `attributes.capability`, und ueber 19 Familiengraphen ist jedes dieser Attribute 0-mal gesetzt (305 MOD, 696 FUNC). Beleg beidseitig: `report:silence` meldet alle sechs mit 0 Befunden ueber den gesamten Bestand, UND keine von ihnen hat eine Ausloese-Fixture in se-rule-trigger-proof.test.ts (CR-SM-285) -- also weder feuert sie irgendwo, noch ist belegt, dass sie ueberhaupt feuern KANN. Genau die Doppelbedingung, die Gate 7 fuer eine Streichung verlangt. NICHT gestrichen wurde CL-01, obwohl derselbe Verdacht bestand: sie feuert 2x in 1 von 19 Graphen. Ihre Aussage waere anderswo besser aufgehoben -- jeder UC muss hinreichend distinct sein, und das saehe man an der FCHAIN -- aber diese Regel EXISTIERT NICHT: CR-SM-283 hat AO-D03 geloescht und dabei festgehalten, dass ihre Aufgabe ('zwei Wirkketten, die auf einer Ebene mitgliedsgleich werden') ungeloest bleibt. CL-01 zu streichen hiesse, eine feuernde Pruefung gegen eine nicht existierende zu tauschen. Wirkung auf die Bestandsgraphen: 0 -> 0 Befunde, kein Graph faellt. Die einzige messbare Folge ist der kleinere NENNER jeder readiness-Dimension -- sechs stumme Regeln hoben bisher jeden Score. Prior: BREAKING (CR-SM-286): ND-01/ND-02 rechnen ihre Aehnlichkeit SELBST; setND01SimilarityMatrix/setND02SimilarityMatrix/getND02SimilarityMatrix entfallen ersatzlos. Die Formel stand als Prosa in contracts und als Code in graphcode/src/kernel/measure/nd-similarity.ts, verbunden durch eine Injektionsnaht. Vier gemessene Kosten: (1) FAIL-OPEN -- ohne Injektion gaben zwei `error`-Regeln [] zurueck, ununterscheidbar von 'keine Duplikate'; moneyflow trug 16 ND-01-Befunde, die ausserhalb graphcodes NIEMAND sah (report:silence, die Spike-Skripte, jedes kuenftige Werkzeug). Die Familie hat fuer 'kann nicht urteilen' eine Konvention (policy.X = null, moduleMetrics.instability = null); ND fiel statt dessen nach gruen. (2) PROZESSWEITER MODULZUSTAND -- `let _nd01Matrix` ist global, graphcode brauchte die Klammer withNDMatrices mit finally-Reset, jeder andere Aufrufer nicht: Graph A urteilte ueber Graph B. (3) AO-D01 liegt IM Gate-Katalog und uebersprang seine Overlap-Pruefung ohne Matrix ('no matrix -> assume pass') -- eine Gate-Regel, die sich stillschweigend abschwaecht. (4) BQ-04 haengt am selben Muster und ist komplett tot. Jetzt: similarity.ts, je Graph WeakMap-gecacht, Formeln und Schwelle 0,85 zeichengleich uebernommen -- dasselbe Urteil an der richtigen Stelle, Praezedenz CR-SM-276 (moduleCrossings). DABEI GEFUNDEN UND BEHOBEN: die portierte Formel las Partner ueber ALLE Traces; se-rule-pair-legality (Pruefung A, CR-SM-278) meldete 35 Faelle, in denen ND-02 erst durch eine grammatikwidrige Kante auf SCHEMA anschlug (ACTOR -compose-> SCHEMA und Verwandte). `partners()` filtert jetzt ueber isValidTrace -- eine Regel darf ihr Verdikt nicht an einer Kante haengen, die R-18 als error ablehnt. Golden bewusst neu verankert und im Test-Header aufgeschluesselt: ssot 98 -> 98 UNVERAENDERT, n700 1038 -> 1478, n3500 5176 -> 17496, der gesamte Zuwachs ist ND-01 auf den synthetischen Eingaengen -- buildFixedSizeGraph KOPIERT den Basisgraphen 11x bzw. 56x, dort hat jedes Element 10 bzw. 55 exakte Duplikate; eine Duplikatsregel MUSS das melden. ND-02 bleibt ueberall 0. BQ-04 ausdruecklich NICHT angeschlossen: es verlangt 'pre-computed EMBEDDING similarity', und Embeddings kann ein reines Vertragspaket nicht rechnen; ein Ersatzmass haette ich erfinden muessen, und der Versuch (0.7*Beschreibung + 0.3*Name) lieferte 0 Befunde an allen neun Familiengraphen und 4950 an einer templatierten Fixture -- beide Gate-7-Ausreisser zugleich. BQ-04 ist damit der naechste AO-D03-Fall und ein eigener se-grammar-review-Vorgang. Prior: BREAKING (CR-SM-285): R-12 findet Zyklen JEDER Laenge statt nur Rueckkanten. Die Regel heisst 'No circular dependencies' und prueft bis hierher nur, ob eine Kante DIREKT zurueckliuft (A->B und B->A). Ein Dreierzyklus A->B->C->A ging vollstaendig durch das Gate, mit null Fehlern. Das ist die gefaehrlichere Haelfte der Fehlerklasse dieser Session: ein Absturz meldet sich, eine Pruefung die ihren Gegenstand nicht erreicht BESTAETIGT. Warum es zaehlt: jeder Rollup der Familie setzt Azyklizitaet voraus -- chainOf/funcChainOf (CR-SM-282/-283) tragen seen-Guards gegen genau diese Endlosschleife, moduleMetrics, die RD-04-Breitenzaehlung und gves Container-Sicht ebenso; unter einem Zyklus ist ein Rollup nicht falsch sondern UNDEFINIERT. Das R-18-Bein aus CR-SM-283 deckt es NICHT: bei A->B->C->A hat jeder Knoten genau EINEN compose-Elternteil, die Baum-Eigenschaft ist formal erfuellt und die Struktur trotzdem kein Baum. Gemessen ueber NEUN Familiengraphen: 0 Zyklen jeder Laenge, also 0 -> 0 Befunde -- die Schaerfung laesst keinen bestehenden Graphen fallen. Major nach Gate 8 trotzdem, weil eine verschaerfte Regel fremde Graphen fallen lassen KANN. EIN Befund je Zyklus statt je Kante (Klasse CR-SM-242), verankert am kleinsten Knoten des Rings und damit unabhaengig vom DFS-Einstieg (Gate 5); die Zweierring-Meldung ist woertlich unveraendert. Dazu zwei Haertungen OHNE Regelwirkung: descriptionOf() gab `el.description ?? ''` und starb an jedem Nicht-String (42/{}/[]/true -> '.trim is not a function', vier von fuenf Typen) -- am Gate hiess das Stacktrace statt block-Verdict; jetzt zaehlt nur ein echter String, alles andere ist 'keine Beschreibung'. Und tests/unit/se-rule-trigger-proof.test.ts ist die Umkehrung von report:silence: je Regel ein Graph der sie feuern LASSEN MUSS, 22 belegt, 50 als unbelegt ausgewiesen mit einer Zahl die nur sinken darf. Beim ersten Lauf fand er sofort einen Fall: ND-01/ND-02 sind `error` und beginnen mit `if (!_nd01Matrix) return []` -- ohne injizierte Aehnlichkeitsmatrix fallen sie nach GRUEN, ununterscheidbar von 'keine Duplikate'. Dokumentiert und eingefroren, nicht behoben: die Severity-/Signalfrage ist ein eigener se-grammar-review-Vorgang. Prior: BREAKING (CR-SM-283): AO-D03 entfaellt ERSATZLOS, BW-02 kommt -- Katalog 74 -> 74, kein Wachstum im Komplexitaetsbudget. (1) AO-D03 (`DuplicatePathDetection`) suchte `FUNC -io-> FUNC`, ein Paar das TRACE_PATTERNS nicht kennt und das R-18 als error ablehnt: die Regel konnte STRUKTURELL nicht feuern und hat es an keinem der fuenf Familiengraphen je getan. Eine Regel die nie feuert kostet trotzdem Nenner-Anteil, Katalogzeile, readiness-Zuordnung, Golden-File-Eintrag und einen Leser der sie unterscheiden muss. Die Aufgabe die sie tragen SOLLTE -- zwei Wirkketten die auf einer Ebene mitgliedsgleich werden -- bleibt ungeloest und ist ein eigener CR; BW-02 ersetzt sie nicht. (2) BW-02 misst die Randbreite der FUNC-WHITEBOX: verschiedene SCHEMA-Vertraege auf `FUNC -io-> FLOW -io-> FUNC` mit einem Endpunkt im compose-Teilbaum und einem ausserhalb. Gerechnet im selben Durchlauf wie `byModule` (module-crossings.ts), damit es EINE Definition von Rand gibt. Der Rollup ist hier nicht Genauigkeit sondern Existenz: ein zerlegter FUNC traegt selbst keine io-Kanten (die liegen an seinen Blaettern), ohne Teilbaum-Aufloesung waere die Zahl strukturell immer 0 -- gemessen FUNC-block-grounding 0 -> 19. Gate 6 des Grammatik-Reviews: 12 Befunde an graphcode, davon 0 in Ueberlappung mit irgendeiner FUNC-Regel (AO-D01 misst Relay-Knoten, IO-01 Kettenkohaerenz, R-31 blosse Verdrahtung). Schwelle 5 aus der Verteilung ABGELESEN, nicht gewaehlt: bok und graph-view-edit enden beide bei 3, graphcode geht bis 19, moneyflow bis 17. Kein info-Level -- bei Schwelle 3 truege bok 4 Befunde auf 9 Blackboxes, und readiness zaehlt info ungefiltert in den Nenner (MT-03-Praezedenz). (3) VIERTES BEIN von R-18: ein Element hat hoechstens einen compose-Elternteil (FUNC/FUNC und MOD/MOD), error. TRACE_PATTERNS begrenzt heute nur die KINDER einer Kante, nie die ELTERN -- graph_mutate legt eine zweite compose-Kante anstandslos an. 0 Verstoesse ueber fuenf Graphen, und trotzdem hart, weil jeder Rollup der Familie unter Verletzung nicht falsch sondern UNDEFINIERT ist (byModule/byFunc, RD-04-Breite, die Container-Sicht von gve). Keine eigene Regel-ID, Praezedenz CR-SM-271 Teil 2: dieselbe Aussage, derselbe naechste Schritt. EIN Befund je KIND, nicht je ueberzaehliger Kante. (4) `policy.boundaryWidth` neu (nullable, Default {warning: 5}) -- fuer Konstruierer einer MetricPolicy breaking. Prior: BREAKING (CR-SM-282): zwei Blackbox-Luecken geschlossen, und beide lassen bestehende Graphen fallen. (1) RD-04 zaehlt den FUNC-WURZELWALD, verankert am SYS-Knoten. Die Regel zaehlt Kinder je Parent; die Wurzeln des `FUNC -compose-> FUNC`-Waldes haben keinen, also war die oberste Funktionsebene unsichtbar -- gemessen: moneyflow hat 306 Wurzel-FUNCs und RD-04 meldete 0. Die MOD-Seite hatte das Problem nie, weil `SYS -compose-> MOD` eine echte Kante ist; die FUNC-Seite hat keine (`se:top-level`: der obere FUNC-Satz ist eine PROJEKTION, keine Kante). Anker ist der einzige SYS-Knoten; gibt es nicht genau einen, schweigt der Zweig statt zu raten (R-17 deckt den Fall). (2) `moduleCrossings.byModule` und die Groesse in R-04 lesen jetzt die BESITZKETTE (direkt alloziertes MOD + compose-Vorfahren) statt nur der direkten Allokation. Ein Eltern-MOD hat keine direkt allozierten FUNCs -- es kam in `byModule` nicht vor, `funcCount` war 0, und R-04 schwieg per `funcCount <= coupled` an genau der Whitebox, in die der Leser hineinklickt. `pairs` (CR-01) bleibt BEWUSST auf der direkten Zuordnung: 'wie stark haengen DIESE zwei Module aneinander' ist eine Blattebenen-Frage, ein Elternpaar meldete dieselbe Kopplung ein zweites Mal -- CR-01 ist an allen fuenf Familiengraphen zeichengleich geblieben (5/3/15/0/63). Delta gesamt: moneyflow RD-04 +1, sirail R-04 +1, bok/gve/graphcode unveraendert. (3) Die Schwelle steht in `policy.decompositionBreadth` statt als `DECOMPOSITION_BREADTH_MAX = 11` inline in rules.ts -- dieselbe Klasse, die CR-SM-236 fuer R-04 aufgeloest hat; `null` schaltet die Regel ab, Default 11 = verhaltensgleich. Das neue Pflichtfeld in MetricPolicy ist fuer Konstruierer breaking. Die Doktrin-Zahl 5 (`se:top-level`) ist bewusst NICHT der Default: `info` bei 5 haette an graphcode 20 zusaetzliche Befunde erzeugt, und readiness zaehlt `info` ungefiltert in den Nenner (`score = 1 - Verstoesse / applicable`) -- genau der Grund, aus dem MT-03 zur Messung statt zur Regel wurde (readiness.ts). Wer doktrin-streng fahren will, setzt 5. Prior: BREAKING (CR-SM-271 Teil 2): SC-04 entfaellt ersatzlos. Ein FLOW ohne SCHEMA ist kein schwaecherer Typ, sondern untypisiert — die Untergrenze ist Grammatik geworden (`FLOW -relation-> SCHEMA [1..1]`, META_MODEL 5.0.0) und meldet als drittes Bein von R-18 (error, mit candidate_targets im Kontext wie zuvor SC-04). Kein Regel-Loch: derselbe Sachverhalt, EIN Befund, nur haerter und am Gate durchgesetzt statt nur gemeldet. Der Katalog schrumpft um eine Zeile (Nenner, readiness-Zuordnung 'schema'/CDR und Golden-File-Eintrag fallen mit); der Fall zaehlt jetzt unter R-18/'arch'/PDR.
|
|
8
|
+
export const RULES_VERSION = '19.2.0'; // MINOR (CR-SM-305): die sechs RC-Regeln stehen im KATALOG -- ALL_RULE_DEFS 63 -> 69, mit eigenem Profil `conformance`. Reine Ergaenzung: keine bestehende Regel, Severity oder Schwelle aendert sich, kein Graph faellt, das Golden-File der Regelausgabe steht zeichengleich. ROOT CAUSE: das Kongruenz-Urteil existierte, war getestet und erreichte KEINEN Produktionspfad. Gate (`harness.mutate`), Steuerung (fit-advisory, steering-snapshot) und `GET /api/graph/readiness` lesen alle ALL_RULE_DEFS; RC stand nicht darin, weil seine Signatur `(graph, facts: CodeFacts)` statt `(graph, policy)` ist -- der einzige Aufrufer von `scoreReadinessWithConformance` war ein Test. Ein Modell-Zug, der die Bindung an den Code bricht, passierte damit jedes Gate lautlos. `evaluateAllRules` fuehrt RC weiterhin NICHT aus (es hat keine CodeFacts), und genau diese Differenz ist das Signal: deklariert und nicht ausgewertet heisst NICHT GEPRUEFT; die vorhandene Ableitung `ALL_RULE_DEFS minus ausgewertet` macht es von selbst laut -- kein zweiter Zweig, die ND-fail-open-Lehre aus CR-SM-286. `domain` ist NEU an `ConformanceRuleDefinition` und fuer Konstruierer breaking; die Werte sind GEMESSEN statt gesetzt (der Entwurf des CR schlug `['code']`, `['code','interface']` vor -- `domain` ist aber die Grundgesamtheit, und 'code' ist kein Elementtyp): RC-01 10x FUNC, RC-04 4x SCHEMA, RC-05 5x MOD ueber fuenf Familien-Repos, RC-02/RC-03 aus der Schleife gelesen (TEST/SCHEMA), RC-06 aus ELEMENT_ATTRIBUTES -- nur FUNC/MOD/SCHEMA duerfen `external` + `realRef` tragen. NICHT in RULE_TO_DIMENSION/RULE_TO_PHASE, und das ist die zweite Korrektur am eigenen Entwurf: der readiness-Nenner summiert die Grundgesamtheiten der Regeln einer Dimension, eine deklarierte und nicht ausgewertete Regel HEBT also den Score. Gemessen ueber vier Repos, was das geschenkt haette: graph-view-edit `schema` +5,0 Punkte (Nenner 24 -> 40), graphify `arch` +2,1 und `ver` +1,8, alles Uebrige <= 0,2 -- der Ausschlag sitzt genau in der kleinen Dimension, wo die Zahl am meisten wiegt. `computeApplicable` ueberspringt eine Regel ohne Dimension bereits von selbst; die beiden Vollstaendigkeitstests sind auf die AUSGEWERTETEN Profile eingeengt (READINESS_SCORED_PROFILES) und haben das seit CR-228 in ihrem eigenen Kopf behauptet -- nur war der Katalog bis hierher mit den ausgewerteten Regeln identisch. Der Ausloese-Beleg (CR-SM-285) gilt auch fuer RC: sechs synthetische CodeFacts-Fixturen, kein Checkout, wie `CodeFactsSchema` es seit CR-211 zusagt ('testable without any filesystem') -- die Zahl der unbelegten Regeln bleibt 42 und ist nicht um sechs gestiegen. In se-engine deckt CLASS_MAP die sechs als Constraint ab: wohin eine verwaiste realRef zeigen SOLL, steht in keinem Feld, ein Operator daraus waere geraten. Prior: MINOR (CR-SM-300): `RULE_HELP` -- die Regelhilfe liegt neben der Regel. Reine ERGAENZUNG: kein Katalogeintrag, keine Severity, keine Schwelle aendert sich, kein bestehender Graph faellt. Warum sie umzieht: ein Hilfeeintrag ist keine Annotation UEBER einer Regel, er ist Teil ihrer LIEFERUNG -- eine Regel, deren Befund niemand lesen kann, ist nicht fertig. CR-GC-227 hat die Schicht 2025 bewusst in graphcode gelassen (Tempo: kein Bump, kein Familien-Review) und die Verschiebung ausdruecklich als spaetere Entscheidung notiert; Gate 1 verlangt fuer das Wiederaufmachen eine MESSUNG, und die lag am 2026-09-08 vor: von 73 Eintraegen in graphcodes `HELP_CONTENT` zeigten 11 auf Regel-IDs, die es nicht mehr gab (R-03, R-14, R-27, FC-01, SC-04, CR-R04, AO-D01, AO-D03, RT-01, PH-01, CA-01 -- AO-D03 seit drei Wochen), waehrend 8 Katalogregeln ganz ohne Eintrag dastanden (BW-02, BQ-01, BQ-02, BQ-04, BQ-06, BQ-07, ND-01, ND-02) -- darunter mit BW-02 eine der vier STEUERDIMENSIONEN: eine Regel, die rankt und sich nicht erklaert. Die Drift lief in beide Richtungen und ueber vier Releases, obwohl graphcode sehr wohl eine Vorwaertspruefung hat (`tests/help-content.test.ts`) -- sie war rot und blieb es, weil niemand graphcodes Suite las (CR-GC-488). Eine Pruefung im ungelesenen Repo ist keine Pruefung, und hinter einem Symlink gilt kein Versionsbereich (CR-GC-488 Paragraph 1a). Co-located zwingt die Grammatik selbst: eine Streichung nimmt den Eintrag mit, eine Neuanlage kann ohne ihn nicht landen. Umfang: 69 Eintraege (63 Katalog- + 6 Conformance-Regeln), 18,6 KB reine Strings -- der ./browser-Eintrag bleibt transitiv `node:`-frei (CR-SM-230). Im Golden-File steht nur die SCHLUESSELMENGE (`ruleHelp`), nicht die Prosa: 'Prosa ist ein Patch-Bump, keine Grammatik' (CR-SM-244) -- ein umformulierter Satz darf keinen Bump ausloesen, ein weggefallener Eintrag muss. Abgrenzung zu `fix_hint`, das an jeder Regeldefinition schon steht (Gate 3): `fix_hint` ist die Anweisung an den AGENTEN, `plain`/`se` die Erklaerung fuer den MENSCHEN -- verschiedene Leser, verschiedene Laenge, verschiedene Sprache. NICHT mitgezogen und bewusst in graphcode geblieben: Dashboard-Panels, Artefakte, das Vokabular und die sechs Metrik-Dimensionen (`HELP_METRICS`, CR-GC-458) -- sie haengen an graphcodes Oberflaeche, nicht am Regelkatalog. Prior: BREAKING (CR-SM-293): MT-01 zaehlt KOPPLUNG statt aller Kanten, dreht die Richtung um und urteilt per Default nicht mehr. (1) fan_in/fan_out lasen bis hierher JEDE Kante, deren eines Ende einem Modul gehoerte. Gemessen ueber 19 Familiengraphen: von 3281 gezaehlten Kanten sind nur 1117 (34 %) Kopplung. fan_in 2164 = 674 `allocate` -- das ist die MODULGROESSE, ein Modul wurde also stabiler, indem es Funktionen bekam -- plus 610 `FLOW -io-> FUNC`, 348 `FCHAIN -compose-> FUNC`, 255 `CR -relation-> FUNC`, 277 Rest. fan_out 1117 = 507 `FUNC -io-> FLOW` plus 501 `FUNC -satisfy-> REQ`; fast die halbe fan_out war SPEZIFIKATION, dieselbe Begruendung, mit der CR-SM-297 `satisfy` aus LCOM4 genommen hat. Dazu 70 Kanten ueber `MOD -io-> MOD`, ein Muster, das CR-SM-266 D2 aus TRACE_PATTERNS geloescht hat. MT-01 liest jetzt `moduleCrossings` -- DIESELBE Definition von Rand und dieselbe Zaehlbasis (verschiedene Vertraege), die CR-01, R-04 und BW-02 seit CR-SM-274/276 benutzen; MT-01 hatte bis hierher noch eine dritte. (2) RICHTUNG: der KONSUMENT haengt ab. Wer nach draussen liefert, wird gebraucht (afferent, fan_in); wer von draussen bezieht, haengt ab (efferent, fan_out). Das ist Martins Ca/Ce; die alte Lesart 'Kante zeigt weg = Abhaengigkeit' drehte jedes reine Verbrauchermodul auf I = 0 (maximal stabil), wo es 1 sein muss. Die Konvention stand vorher NIRGENDS im Repo -- sie war nie entschieden, nur codiert. (3) `DEFAULT_METRIC_POLICY.instability` 0.7 -> null, messen statt urteilen. Die Verteilung ist zweigipflig -- 44 von 149 messbaren Modulen exakt auf 0.00, 45 exakt auf 1.00, und 45 der 51 Befunde bei 0.7 sind genau diese 1.00 -- aus ihr laesst sich keine Schwelle ABLESEN (Praezedenz CR-SM-283/BW-02). Tiefer: I ist eine KOORDINATE, kein Defekt; Martins Satz lautet 'in Richtung Stabilitaet abhaengen', nicht 'I klein halten'. Damit fehlt MT-01 die Eigenschaft, die CR-SM-287 §2 von einer Steuerdimension verlangt (gerichtet, 'weniger ist besser, ohne Diskussion'), und (4) `STEER_RULES` schrumpft auf VIER. Praktisch war die Dimension ohnehin still: `steerScore` liest Verstoesse, und graphcodes Config setzt `instability: null` seit CR-GC-329 -- auf dem einzigen Repo, das taeglich steuert, lief der R5 laengst als R4. Der Nachfolger ist gemessen und angelegt (CR-SM-298): Martins Stable Dependencies Principle als gerichtete Groesse, Abhaengigkeiten 'bergauf' je Modul -- 34 von 305 (11 %), 132 von 146 Modulen bei null, Schwanz bis 6; lokal, gerichtet, budgetierbar, nicht entartet. Die Zahl `instability` bleibt vollstaendig erhalten: graph_metrics, Export und das gve-Dashboard rendern sie weiter, letzteres samt Hinweis 'Instabilitaet wird hier nur gemessen'. Prior: BREAKING (CR-SM-297, Teil 1): `satisfy` faellt aus der LCOM4-Verbindung von MT-02. Die Regel misst KOHAESION, und Kohaesion ist Datenkopplung -- geteilte `io`-Ziele und geteilte FLOW. `satisfy` ist dagegen eine SPEZIFIKATIONS-Beziehung: zwei FUNCs, die dasselbe REQ erfuellen, koennen zur Laufzeit vollstaendig entkoppelt sein. Die Wirkung ging dabei nur in EINE Richtung -- `satisfy` verbindet Gruppen, senkte also LCOM4 und liess Module kohaesiver aussehen, als ihr Datenfluss hergibt. Der Modellierungsgrund wiegt schwerer als der Messgrund: teilen sich zwei Funktionen ein Requirement, ist das REQUIREMENT zu zerlegen, nicht die Kohaesionsmessung zu beschoenigen; RD-02 sagt bereits das Verwandte. Gemessen ueber 19 Familiengraphen: MT-02 23 -> 24 Befunde. `satisfy` hat also fast nie zwei Gruppen verbunden -- die Aenderung ist prinzipiell richtig und praktisch billig. Golden neu verankert OHNE Zahlenaenderung: Totals und Reihenfolge bleiben an allen drei Eingaengen gleich (ssot 99, n700 1475, n3500 17495), nur die MT-02-shas wandern, weil die Meldung den gemessenen LCOM4-Wert woertlich nennt. NOCH OFFEN aus CR-SM-297: die beiden Container-Masse fuer den zerlegten FUNC (Kohaesion analog MT-02, Paar-Kopplung analog CR-01) -- ihre Schwellen sind aus der Verteilung ABZULESEN, nicht zu setzen (Praezedenz CR-SM-283/BW-02). Prior: BREAKING (CR-SM-296): je Frage eine Regel, je Schwelle ein Wert. (1) RD-04 gibt das Bein `FUNC -allocate-> MOD` an R-04 ab. Es zaehlte die allozierten FUNCs je Modul -- also die MODULGROESSE, und die misst R-04 auch. Beide feuerten am selben Modul im selben Batch, mit zwei Schwellen aus zwei Policy-Feldern (RD-04 > 11 gegen R-04 > 12), und welche recht hat, stand nirgends; dieselbe Ursache ging doppelt in den readiness-Nenner. R-04 ist die reichere Aussage -- Groesse GEGEN Kreuzungen, drei Urteile -- und liest ueber moduleCrossings ohnehin dieselben Daten. RD-04 bleibt fuer ZERLEGUNGSBREITE zustaendig: FUNC compose FUNC, SYS/MOD compose MOD und der FUNC-Wurzelwald am SYS (CR-SM-282). (2) Beide Schwellen sind an die Doktrin 7+-2 gebunden statt danebengesetzt: decompositionBreadth.warning 11 -> 9 (die Obergrenze der Doktrin) und moduleSize large 12 -> 9, coupled 8 -> 7. CR-SM-282 hatte gegen die Doktrin-Zahl 5 entschieden, weil `info` bei 5 den readiness-Nenner verwaessert haette -- das Argument traegt fuer die OBERgrenze nicht, denn RD-04 meldet als warning. Wirkung ueber 19 Familiengraphen, gemessen: RD-04 17 -> 15, R-04 9 -> 11, Summe 26 -> 26. Die Zahl bleibt, die Zustaendigkeit wird eindeutig. Prior: BREAKING (CR-SM-295): drei Regeln entfallen, eine wird neu gefasst -- Katalog 66 -> 63. (1) R-14 (UC must have compose) kann NIE ALLEIN feuern: sie prueft nur, ob ein UC irgendeine ausgehende compose-Kante hat, ohne den Zieltyp anzusehen, waehrend UC-01 den REQ und UC-03 die FCHAIN einzeln verlangen. Auf ELEMENTEBENE ueber 19 Familiengraphen gemessen, nicht auf Summen: R-14 (2 Befunde) ist eine echte Teilmenge von UC-01 vereinigt UC-03 (23 Befunde). Ihr Fixhinweis ('Add FCHAIN or REQ') versprach zudem eine Pruefung, die der Code nicht macht. (2) FC-01 (FCHAIN has actor boundary) ist von FC-04 gedeckt -- gemessen FC-01 (5) Teilmenge von FC-04 (27); FC-04 verlangt Eingang UND Ausgang, FC-01 nur eine Beruehrung. Dazu trug FC-01 einen TOTEN Ersatzweg: `hasDirectActorIO` prueft, ob der Eltern-UC actor-adjazent ist, und `ACTOR -io-> UC` hat CR-SM-266 (D1/D4) aus TRACE_PATTERNS entfernt -- der Zweig konnte seit drei Versionen nicht mehr wahr werden. (3) CR-R04 entfaellt und CR-R01 wird NEU GEFASST. Beide zielten daneben: CR-R01 akzeptierte jede relation-Kante, also auch einen CR, der nur an einem Meilenstein haengt (Termin, kein Umfang) -- 5 Befunde bei 49 CRs, die ausschliesslich auf ein MS zeigen. CR-R04 verlangte einen FUNC und war damit zu eng: 21 Befunde, darunter Daten-, Doku- und Konfigurationsaenderungen, die zu Recht keine Funktion beruehren. Die neue Fassung fragt nach dem UMFANG: mindestens eine relation auf FUNC, MOD, SCHEMA, REQ oder UC. Grundgesamtheit woertlich die von CR-R04 (CR-SM-255, nur offene CRs) -- an einem geschlossenen CR ist die Frage Archaeologie. Gemessen an 514 CR-Knoten: 54 ohne Umfangsbezug, davon 0 OFFEN, 52 done, 2 ohne Status. Die Verschaerfung laesst die Historie damit unangetastet und wirkt ab dem naechsten CR. MS-03 (CR ohne MS) bleibt unberuehrt -- sie stellt die komplementaere Frage. (4) R-17 behaelt ihre Pruefung und verliert ihren falschen Fixhinweis, der drei Zieltypen nannte, die sie nie angesehen hat. Prior: BREAKING (CR-SM-294): sechs Regeln entfallen ersatzlos, Katalog 72 -> 66. AO-D01 (RelayNodeDetection) ist STRUKTURELL unmoeglich -- sie verlangt `>= 2` ausgehende `io`-Kanten auf andere FUNC, und `FUNC -io-> FUNC` steht nicht in TRACE_PATTERNS; R-18 lehnt es als error ab. Das ist zeichengleich der Fall, fuer den CR-SM-283 AO-D03 geloescht hat -- AO-D03 fiel, AO-D01 blieb stehen. CA-01, RT-01, PH-01, R-27 und R-03 sind GEGENSTANDSLOS: sie lesen `asil`, `attributes.kind === 'physical'`, `attributes.requires` und `attributes.capability`, und ueber 19 Familiengraphen ist jedes dieser Attribute 0-mal gesetzt (305 MOD, 696 FUNC). Beleg beidseitig: `report:silence` meldet alle sechs mit 0 Befunden ueber den gesamten Bestand, UND keine von ihnen hat eine Ausloese-Fixture in se-rule-trigger-proof.test.ts (CR-SM-285) -- also weder feuert sie irgendwo, noch ist belegt, dass sie ueberhaupt feuern KANN. Genau die Doppelbedingung, die Gate 7 fuer eine Streichung verlangt. NICHT gestrichen wurde CL-01, obwohl derselbe Verdacht bestand: sie feuert 2x in 1 von 19 Graphen. Ihre Aussage waere anderswo besser aufgehoben -- jeder UC muss hinreichend distinct sein, und das saehe man an der FCHAIN -- aber diese Regel EXISTIERT NICHT: CR-SM-283 hat AO-D03 geloescht und dabei festgehalten, dass ihre Aufgabe ('zwei Wirkketten, die auf einer Ebene mitgliedsgleich werden') ungeloest bleibt. CL-01 zu streichen hiesse, eine feuernde Pruefung gegen eine nicht existierende zu tauschen. Wirkung auf die Bestandsgraphen: 0 -> 0 Befunde, kein Graph faellt. Die einzige messbare Folge ist der kleinere NENNER jeder readiness-Dimension -- sechs stumme Regeln hoben bisher jeden Score. Prior: BREAKING (CR-SM-286): ND-01/ND-02 rechnen ihre Aehnlichkeit SELBST; setND01SimilarityMatrix/setND02SimilarityMatrix/getND02SimilarityMatrix entfallen ersatzlos. Die Formel stand als Prosa in contracts und als Code in graphcode/src/kernel/measure/nd-similarity.ts, verbunden durch eine Injektionsnaht. Vier gemessene Kosten: (1) FAIL-OPEN -- ohne Injektion gaben zwei `error`-Regeln [] zurueck, ununterscheidbar von 'keine Duplikate'; moneyflow trug 16 ND-01-Befunde, die ausserhalb graphcodes NIEMAND sah (report:silence, die Spike-Skripte, jedes kuenftige Werkzeug). Die Familie hat fuer 'kann nicht urteilen' eine Konvention (policy.X = null, moduleMetrics.instability = null); ND fiel statt dessen nach gruen. (2) PROZESSWEITER MODULZUSTAND -- `let _nd01Matrix` ist global, graphcode brauchte die Klammer withNDMatrices mit finally-Reset, jeder andere Aufrufer nicht: Graph A urteilte ueber Graph B. (3) AO-D01 liegt IM Gate-Katalog und uebersprang seine Overlap-Pruefung ohne Matrix ('no matrix -> assume pass') -- eine Gate-Regel, die sich stillschweigend abschwaecht. (4) BQ-04 haengt am selben Muster und ist komplett tot. Jetzt: similarity.ts, je Graph WeakMap-gecacht, Formeln und Schwelle 0,85 zeichengleich uebernommen -- dasselbe Urteil an der richtigen Stelle, Praezedenz CR-SM-276 (moduleCrossings). DABEI GEFUNDEN UND BEHOBEN: die portierte Formel las Partner ueber ALLE Traces; se-rule-pair-legality (Pruefung A, CR-SM-278) meldete 35 Faelle, in denen ND-02 erst durch eine grammatikwidrige Kante auf SCHEMA anschlug (ACTOR -compose-> SCHEMA und Verwandte). `partners()` filtert jetzt ueber isValidTrace -- eine Regel darf ihr Verdikt nicht an einer Kante haengen, die R-18 als error ablehnt. Golden bewusst neu verankert und im Test-Header aufgeschluesselt: ssot 98 -> 98 UNVERAENDERT, n700 1038 -> 1478, n3500 5176 -> 17496, der gesamte Zuwachs ist ND-01 auf den synthetischen Eingaengen -- buildFixedSizeGraph KOPIERT den Basisgraphen 11x bzw. 56x, dort hat jedes Element 10 bzw. 55 exakte Duplikate; eine Duplikatsregel MUSS das melden. ND-02 bleibt ueberall 0. BQ-04 ausdruecklich NICHT angeschlossen: es verlangt 'pre-computed EMBEDDING similarity', und Embeddings kann ein reines Vertragspaket nicht rechnen; ein Ersatzmass haette ich erfinden muessen, und der Versuch (0.7*Beschreibung + 0.3*Name) lieferte 0 Befunde an allen neun Familiengraphen und 4950 an einer templatierten Fixture -- beide Gate-7-Ausreisser zugleich. BQ-04 ist damit der naechste AO-D03-Fall und ein eigener se-grammar-review-Vorgang. Prior: BREAKING (CR-SM-285): R-12 findet Zyklen JEDER Laenge statt nur Rueckkanten. Die Regel heisst 'No circular dependencies' und prueft bis hierher nur, ob eine Kante DIREKT zurueckliuft (A->B und B->A). Ein Dreierzyklus A->B->C->A ging vollstaendig durch das Gate, mit null Fehlern. Das ist die gefaehrlichere Haelfte der Fehlerklasse dieser Session: ein Absturz meldet sich, eine Pruefung die ihren Gegenstand nicht erreicht BESTAETIGT. Warum es zaehlt: jeder Rollup der Familie setzt Azyklizitaet voraus -- chainOf/funcChainOf (CR-SM-282/-283) tragen seen-Guards gegen genau diese Endlosschleife, moduleMetrics, die RD-04-Breitenzaehlung und gves Container-Sicht ebenso; unter einem Zyklus ist ein Rollup nicht falsch sondern UNDEFINIERT. Das R-18-Bein aus CR-SM-283 deckt es NICHT: bei A->B->C->A hat jeder Knoten genau EINEN compose-Elternteil, die Baum-Eigenschaft ist formal erfuellt und die Struktur trotzdem kein Baum. Gemessen ueber NEUN Familiengraphen: 0 Zyklen jeder Laenge, also 0 -> 0 Befunde -- die Schaerfung laesst keinen bestehenden Graphen fallen. Major nach Gate 8 trotzdem, weil eine verschaerfte Regel fremde Graphen fallen lassen KANN. EIN Befund je Zyklus statt je Kante (Klasse CR-SM-242), verankert am kleinsten Knoten des Rings und damit unabhaengig vom DFS-Einstieg (Gate 5); die Zweierring-Meldung ist woertlich unveraendert. Dazu zwei Haertungen OHNE Regelwirkung: descriptionOf() gab `el.description ?? ''` und starb an jedem Nicht-String (42/{}/[]/true -> '.trim is not a function', vier von fuenf Typen) -- am Gate hiess das Stacktrace statt block-Verdict; jetzt zaehlt nur ein echter String, alles andere ist 'keine Beschreibung'. Und tests/unit/se-rule-trigger-proof.test.ts ist die Umkehrung von report:silence: je Regel ein Graph der sie feuern LASSEN MUSS, 22 belegt, 50 als unbelegt ausgewiesen mit einer Zahl die nur sinken darf. Beim ersten Lauf fand er sofort einen Fall: ND-01/ND-02 sind `error` und beginnen mit `if (!_nd01Matrix) return []` -- ohne injizierte Aehnlichkeitsmatrix fallen sie nach GRUEN, ununterscheidbar von 'keine Duplikate'. Dokumentiert und eingefroren, nicht behoben: die Severity-/Signalfrage ist ein eigener se-grammar-review-Vorgang. Prior: BREAKING (CR-SM-283): AO-D03 entfaellt ERSATZLOS, BW-02 kommt -- Katalog 74 -> 74, kein Wachstum im Komplexitaetsbudget. (1) AO-D03 (`DuplicatePathDetection`) suchte `FUNC -io-> FUNC`, ein Paar das TRACE_PATTERNS nicht kennt und das R-18 als error ablehnt: die Regel konnte STRUKTURELL nicht feuern und hat es an keinem der fuenf Familiengraphen je getan. Eine Regel die nie feuert kostet trotzdem Nenner-Anteil, Katalogzeile, readiness-Zuordnung, Golden-File-Eintrag und einen Leser der sie unterscheiden muss. Die Aufgabe die sie tragen SOLLTE -- zwei Wirkketten die auf einer Ebene mitgliedsgleich werden -- bleibt ungeloest und ist ein eigener CR; BW-02 ersetzt sie nicht. (2) BW-02 misst die Randbreite der FUNC-WHITEBOX: verschiedene SCHEMA-Vertraege auf `FUNC -io-> FLOW -io-> FUNC` mit einem Endpunkt im compose-Teilbaum und einem ausserhalb. Gerechnet im selben Durchlauf wie `byModule` (module-crossings.ts), damit es EINE Definition von Rand gibt. Der Rollup ist hier nicht Genauigkeit sondern Existenz: ein zerlegter FUNC traegt selbst keine io-Kanten (die liegen an seinen Blaettern), ohne Teilbaum-Aufloesung waere die Zahl strukturell immer 0 -- gemessen FUNC-block-grounding 0 -> 19. Gate 6 des Grammatik-Reviews: 12 Befunde an graphcode, davon 0 in Ueberlappung mit irgendeiner FUNC-Regel (AO-D01 misst Relay-Knoten, IO-01 Kettenkohaerenz, R-31 blosse Verdrahtung). Schwelle 5 aus der Verteilung ABGELESEN, nicht gewaehlt: bok und graph-view-edit enden beide bei 3, graphcode geht bis 19, moneyflow bis 17. Kein info-Level -- bei Schwelle 3 truege bok 4 Befunde auf 9 Blackboxes, und readiness zaehlt info ungefiltert in den Nenner (MT-03-Praezedenz). (3) VIERTES BEIN von R-18: ein Element hat hoechstens einen compose-Elternteil (FUNC/FUNC und MOD/MOD), error. TRACE_PATTERNS begrenzt heute nur die KINDER einer Kante, nie die ELTERN -- graph_mutate legt eine zweite compose-Kante anstandslos an. 0 Verstoesse ueber fuenf Graphen, und trotzdem hart, weil jeder Rollup der Familie unter Verletzung nicht falsch sondern UNDEFINIERT ist (byModule/byFunc, RD-04-Breite, die Container-Sicht von gve). Keine eigene Regel-ID, Praezedenz CR-SM-271 Teil 2: dieselbe Aussage, derselbe naechste Schritt. EIN Befund je KIND, nicht je ueberzaehliger Kante. (4) `policy.boundaryWidth` neu (nullable, Default {warning: 5}) -- fuer Konstruierer einer MetricPolicy breaking. Prior: BREAKING (CR-SM-282): zwei Blackbox-Luecken geschlossen, und beide lassen bestehende Graphen fallen. (1) RD-04 zaehlt den FUNC-WURZELWALD, verankert am SYS-Knoten. Die Regel zaehlt Kinder je Parent; die Wurzeln des `FUNC -compose-> FUNC`-Waldes haben keinen, also war die oberste Funktionsebene unsichtbar -- gemessen: moneyflow hat 306 Wurzel-FUNCs und RD-04 meldete 0. Die MOD-Seite hatte das Problem nie, weil `SYS -compose-> MOD` eine echte Kante ist; die FUNC-Seite hat keine (`se:top-level`: der obere FUNC-Satz ist eine PROJEKTION, keine Kante). Anker ist der einzige SYS-Knoten; gibt es nicht genau einen, schweigt der Zweig statt zu raten (R-17 deckt den Fall). (2) `moduleCrossings.byModule` und die Groesse in R-04 lesen jetzt die BESITZKETTE (direkt alloziertes MOD + compose-Vorfahren) statt nur der direkten Allokation. Ein Eltern-MOD hat keine direkt allozierten FUNCs -- es kam in `byModule` nicht vor, `funcCount` war 0, und R-04 schwieg per `funcCount <= coupled` an genau der Whitebox, in die der Leser hineinklickt. `pairs` (CR-01) bleibt BEWUSST auf der direkten Zuordnung: 'wie stark haengen DIESE zwei Module aneinander' ist eine Blattebenen-Frage, ein Elternpaar meldete dieselbe Kopplung ein zweites Mal -- CR-01 ist an allen fuenf Familiengraphen zeichengleich geblieben (5/3/15/0/63). Delta gesamt: moneyflow RD-04 +1, sirail R-04 +1, bok/gve/graphcode unveraendert. (3) Die Schwelle steht in `policy.decompositionBreadth` statt als `DECOMPOSITION_BREADTH_MAX = 11` inline in rules.ts -- dieselbe Klasse, die CR-SM-236 fuer R-04 aufgeloest hat; `null` schaltet die Regel ab, Default 11 = verhaltensgleich. Das neue Pflichtfeld in MetricPolicy ist fuer Konstruierer breaking. Die Doktrin-Zahl 5 (`se:top-level`) ist bewusst NICHT der Default: `info` bei 5 haette an graphcode 20 zusaetzliche Befunde erzeugt, und readiness zaehlt `info` ungefiltert in den Nenner (`score = 1 - Verstoesse / applicable`) -- genau der Grund, aus dem MT-03 zur Messung statt zur Regel wurde (readiness.ts). Wer doktrin-streng fahren will, setzt 5. Prior: BREAKING (CR-SM-271 Teil 2): SC-04 entfaellt ersatzlos. Ein FLOW ohne SCHEMA ist kein schwaecherer Typ, sondern untypisiert — die Untergrenze ist Grammatik geworden (`FLOW -relation-> SCHEMA [1..1]`, META_MODEL 5.0.0) und meldet als drittes Bein von R-18 (error, mit candidate_targets im Kontext wie zuvor SC-04). Kein Regel-Loch: derselbe Sachverhalt, EIN Befund, nur haerter und am Gate durchgesetzt statt nur gemeldet. Der Katalog schrumpft um eine Zeile (Nenner, readiness-Zuordnung 'schema'/CDR und Golden-File-Eintrag fallen mit); der Fall zaehlt jetzt unter R-18/'arch'/PDR.
|
|
9
9
|
/** Meta-model version (trace pattern constraints + format-e parser). */
|
|
10
10
|
export const META_MODEL_VERSION = '5.0.0'; // BREAKING (CR-SM-271 Teil 2): `FLOW -relation-> SCHEMA` wird `1..1` — die erste DURCHGESETZTE Untergrenze (minOccurs/REQUIRED_PATTERNS; nur exakt-`1`, die `1..*`-compose-Untergrenzen bleiben Vollstaendigkeits-Warnungen ihrer Regeln). Migrationsbestand vorab abgetragen: graphcode 2, sigloch-modules 4, graph-view-edit 5 (je durchs Gate), urbanmobility-Fixture geloescht (39, Spike ohne Referenzen); sirail 4 offen (EXPORT_PENDING-Divergenz seit 2026-08-18).
|
|
11
11
|
export * from './ontology.js';
|
|
@@ -23,6 +23,16 @@ export * from './cr-quality-rules.js';
|
|
|
23
23
|
export * from './near-duplicate-rules.js';
|
|
24
24
|
export * from './similarity.js';
|
|
25
25
|
export * from './ao-rules.js';
|
|
26
|
+
export * from './rule-help.js';
|
|
27
|
+
/*
|
|
28
|
+
* CR-GVE-281: `moduleCrossings` war nie exportiert — die EINE Definition von „Rand" und von
|
|
29
|
+
* „welche FUNC gehoert zu welchem MOD" (`funcsByModule`, Besitzkette ueber `MOD -compose-> MOD`,
|
|
30
|
+
* CR-SM-282) lag hinter der Paketgrenze. graph-view-edit hat sie deshalb nachgebaut, mit der
|
|
31
|
+
* DIREKTEN allocate-Kante und ohne die Kette: eine FUNC unter einem sichtbaren Eltern-MOD faellt
|
|
32
|
+
* dort aus jedem Container heraus. Zwei Definitionen derselben Zugehoerigkeit sind genau der
|
|
33
|
+
* parallele Pfad, gegen den `module-crossings.ts` gebaut wurde — sie ist ab jetzt erreichbar.
|
|
34
|
+
*/
|
|
35
|
+
export * from './module-crossings.js';
|
|
26
36
|
export * from './quality-rules.js';
|
|
27
37
|
export * from './analysis-freshness-rules.js';
|
|
28
38
|
export * from './evaluate-all.js';
|
package/dist/se/readiness.d.ts
CHANGED
|
@@ -67,6 +67,28 @@ export declare const ReadinessReport: z.ZodObject<{
|
|
|
67
67
|
timestamp: z.ZodISODateTime;
|
|
68
68
|
}, z.core.$strip>;
|
|
69
69
|
export type ReadinessReportType = z.infer<typeof ReadinessReport>;
|
|
70
|
+
/**
|
|
71
|
+
* CR-SM-305 — welche Profile in die readiness-Zahlen eingehen, und warum `conformance` nicht.
|
|
72
|
+
*
|
|
73
|
+
* Der Nenner jeder Dimension ist `Σ (Elemente der Grundgesamtheit)` ueber die Regeln der
|
|
74
|
+
* Dimension (`readiness-compute.ts`). Eine Regel, die DEKLARIERT, aber nicht AUSGEWERTET wird,
|
|
75
|
+
* traegt damit zum Nenner bei und liefert null Verstoesse — der Score STEIGT, weil eine
|
|
76
|
+
* Pruefung nicht gelaufen ist. Dieselbe Fail-open-Klasse wie ND-01/02 vor CR-SM-286, nur an der
|
|
77
|
+
* Stelle, die am lautesten gelesen wird.
|
|
78
|
+
*
|
|
79
|
+
* Gemessen ueber vier Familien-Repos, was die sechs RC-Regeln in `arch`/`ver`/`schema`
|
|
80
|
+
* geschenkt haetten: graph-view-edit `schema` +5,0 Punkte (Nenner 24 → 40), graphify `arch`
|
|
81
|
+
* +2,1 und `ver` +1,8, alles Uebrige ≤ 0,2. Der Ausschlag sitzt genau dort, wo die Zahl am
|
|
82
|
+
* meisten wiegt — in der kleinen Dimension.
|
|
83
|
+
*
|
|
84
|
+
* Deshalb steht keine RC-ID in `RULE_TO_DIMENSION` oder `RULE_TO_PHASE`. Das ist keine Luecke,
|
|
85
|
+
* sondern die Aussage „nicht ausgewertet, also weder Zaehler noch Nenner";
|
|
86
|
+
* `computeApplicable` ueberspringt eine Regel ohne Dimension bereits von selbst
|
|
87
|
+
* (`if (!dim) continue`). Sichtbar wird RC ueber die Ableitung `ALL_RULE_DEFS minus
|
|
88
|
+
* ausgewertet` beim Host: sechs Regeln, die als NICHT GEPRUEFT dastehen, solange kein Lauf
|
|
89
|
+
* `CodeFacts` mitbringt.
|
|
90
|
+
*/
|
|
91
|
+
export declare const READINESS_SCORED_PROFILES: readonly ["se", "coding"];
|
|
70
92
|
/**
|
|
71
93
|
* Rule → dimension mapping. Some rules belong to multiple dimensions;
|
|
72
94
|
* here we assign primary dimension per rule. R-01 appears in 'ver' (primary)
|
package/dist/se/readiness.js
CHANGED
|
@@ -62,6 +62,28 @@ export const ReadinessReport = z.object({
|
|
|
62
62
|
scores: z.array(ReadinessScore),
|
|
63
63
|
timestamp: z.iso.datetime(),
|
|
64
64
|
});
|
|
65
|
+
/**
|
|
66
|
+
* CR-SM-305 — welche Profile in die readiness-Zahlen eingehen, und warum `conformance` nicht.
|
|
67
|
+
*
|
|
68
|
+
* Der Nenner jeder Dimension ist `Σ (Elemente der Grundgesamtheit)` ueber die Regeln der
|
|
69
|
+
* Dimension (`readiness-compute.ts`). Eine Regel, die DEKLARIERT, aber nicht AUSGEWERTET wird,
|
|
70
|
+
* traegt damit zum Nenner bei und liefert null Verstoesse — der Score STEIGT, weil eine
|
|
71
|
+
* Pruefung nicht gelaufen ist. Dieselbe Fail-open-Klasse wie ND-01/02 vor CR-SM-286, nur an der
|
|
72
|
+
* Stelle, die am lautesten gelesen wird.
|
|
73
|
+
*
|
|
74
|
+
* Gemessen ueber vier Familien-Repos, was die sechs RC-Regeln in `arch`/`ver`/`schema`
|
|
75
|
+
* geschenkt haetten: graph-view-edit `schema` +5,0 Punkte (Nenner 24 → 40), graphify `arch`
|
|
76
|
+
* +2,1 und `ver` +1,8, alles Uebrige ≤ 0,2. Der Ausschlag sitzt genau dort, wo die Zahl am
|
|
77
|
+
* meisten wiegt — in der kleinen Dimension.
|
|
78
|
+
*
|
|
79
|
+
* Deshalb steht keine RC-ID in `RULE_TO_DIMENSION` oder `RULE_TO_PHASE`. Das ist keine Luecke,
|
|
80
|
+
* sondern die Aussage „nicht ausgewertet, also weder Zaehler noch Nenner";
|
|
81
|
+
* `computeApplicable` ueberspringt eine Regel ohne Dimension bereits von selbst
|
|
82
|
+
* (`if (!dim) continue`). Sichtbar wird RC ueber die Ableitung `ALL_RULE_DEFS minus
|
|
83
|
+
* ausgewertet` beim Host: sechs Regeln, die als NICHT GEPRUEFT dastehen, solange kein Lauf
|
|
84
|
+
* `CodeFacts` mitbringt.
|
|
85
|
+
*/
|
|
86
|
+
export const READINESS_SCORED_PROFILES = ['se', 'coding'];
|
|
65
87
|
/**
|
|
66
88
|
* Rule → dimension mapping. Some rules belong to multiple dimensions;
|
|
67
89
|
* here we assign primary dimension per rule. R-01 appears in 'ver' (primary)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rule-help.ts — die Regelhilfe liegt NEBEN der Regel (CR-SM-300).
|
|
3
|
+
*
|
|
4
|
+
* Ein Hilfeeintrag ist keine Annotation *ueber* einer Regel, er ist **Teil ihrer Lieferung**:
|
|
5
|
+
* eine Regel, deren Befund niemand lesen kann, ist nicht fertig. Bis hierher lag die Schicht in
|
|
6
|
+
* graphcode (CR-GC-227, bewusst, aus Tempo — dort brauchte sie keinen Bump und kein Review), und
|
|
7
|
+
* derselbe CR hat die Verschiebung ausdruecklich als spaetere Entscheidung notiert. Sie ist jetzt
|
|
8
|
+
* getroffen; der Grund ist die Drift, die sie erzeugt hat: 11 Eintraege zu geloeschten Regeln und
|
|
9
|
+
* 8 Katalogregeln ohne Eintrag, unbemerkt ueber vier Releases. Hinter einem Symlink gilt kein
|
|
10
|
+
* Versionsbereich (CR-GC-488 §1a) — eine Pruefung im ungelesenen Repo ist keine Pruefung.
|
|
11
|
+
*
|
|
12
|
+
* ## Was hier NICHT steht
|
|
13
|
+
*
|
|
14
|
+
* - **Abgeleitetes** — Titel, Severity, Meldung und `fix_hint` stehen an der Regeldefinition
|
|
15
|
+
* (`ALL_RULE_DEFS`), die Dimensions-/Phasenzuordnung in `readiness.ts`. Kein Wort davon wird
|
|
16
|
+
* hier wiederholt; ein zweiter Speicher derselben Wahrheit laeuft auseinander.
|
|
17
|
+
* - **`fix_hint` gegen `plain`/`se`** — `fix_hint` ist die Anweisung an den AGENTEN („Add a
|
|
18
|
+
* `verify` trace"), `plain`/`se` die Erklaerung fuer den MENSCHEN („was ist hier eigentlich
|
|
19
|
+
* kaputt, und wie heisst das in der SE-Literatur"). Verschiedene Leser, verschiedene Laenge,
|
|
20
|
+
* verschiedene Sprache — deshalb drei Felder und nicht eines.
|
|
21
|
+
* - **Nicht-Regel-Hilfe** — Dashboard-Panels, Artefakte, das Vokabular und die sechs
|
|
22
|
+
* Metrik-Dimensionen (`HELP_METRICS`, CR-GC-458) bleiben in graphcode: sie sind an dessen
|
|
23
|
+
* Oberflaeche gebunden, nicht an den Regelkatalog.
|
|
24
|
+
*
|
|
25
|
+
* ## Was die Version haelt
|
|
26
|
+
*
|
|
27
|
+
* **Die PRAESENZ ist Oberflaeche** und haengt an `RULES_VERSION`: eine Regel ohne Hilfeeintrag
|
|
28
|
+
* kann nicht landen, ein Eintrag ohne Regel auch nicht (`tests/unit/se-rule-help.test.ts`,
|
|
29
|
+
* beidseitig, gegen die lebenden Registraturen — nie gegen eine Handzaehlung).
|
|
30
|
+
* **Der TEXT ist es nicht.** „Prosa ist ein Patch-Bump, keine Grammatik" (CR-SM-244): ein
|
|
31
|
+
* umformulierter Satz darf keinen Major ausloesen, deshalb steht im Golden-File nur die
|
|
32
|
+
* Schluesselmenge, nicht die Prosa.
|
|
33
|
+
*
|
|
34
|
+
* Sprache: Englisch, wie die Regelbeschreibungen selbst. 18,6 KB reine Strings — der
|
|
35
|
+
* `./browser`-Eintrag bleibt transitiv `node:`-frei (CR-SM-230), Strings ziehen nichts nach.
|
|
36
|
+
*
|
|
37
|
+
* @author andreas@siglochconsulting
|
|
38
|
+
*/
|
|
39
|
+
/** Ein verfasster Hilfeeintrag: die zwei Klartext-Schichten, dazu ein Kopier-Prompt, wo einer passt. */
|
|
40
|
+
export interface RuleHelpEntry {
|
|
41
|
+
/** Schicht 0 — ohne SE-Jargon; endet mit der EINEN einfachen Handlung. */
|
|
42
|
+
readonly plain: string;
|
|
43
|
+
/** Schicht 1 — uebersetzt unsere Kodierung in den Standardbegriff der Systems-Engineering-Literatur. */
|
|
44
|
+
readonly se: string;
|
|
45
|
+
/** Schicht 2 — ein kopierbarer Prompt (`se:*`-Skill oder MCP-Aufruf), wo einer passt. */
|
|
46
|
+
readonly prompt?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Je Regel-ID der Hilfeeintrag — Katalogregeln (`ALL_RULE_DEFS`) UND Conformance-Regeln
|
|
50
|
+
* (`CODE_CONFORMANCE_RULES`). Vollstaendig in beide Richtungen, erzwungen im Test.
|
|
51
|
+
*/
|
|
52
|
+
export declare const RULE_HELP: Record<string, RuleHelpEntry>;
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rule-help.ts — die Regelhilfe liegt NEBEN der Regel (CR-SM-300).
|
|
3
|
+
*
|
|
4
|
+
* Ein Hilfeeintrag ist keine Annotation *ueber* einer Regel, er ist **Teil ihrer Lieferung**:
|
|
5
|
+
* eine Regel, deren Befund niemand lesen kann, ist nicht fertig. Bis hierher lag die Schicht in
|
|
6
|
+
* graphcode (CR-GC-227, bewusst, aus Tempo — dort brauchte sie keinen Bump und kein Review), und
|
|
7
|
+
* derselbe CR hat die Verschiebung ausdruecklich als spaetere Entscheidung notiert. Sie ist jetzt
|
|
8
|
+
* getroffen; der Grund ist die Drift, die sie erzeugt hat: 11 Eintraege zu geloeschten Regeln und
|
|
9
|
+
* 8 Katalogregeln ohne Eintrag, unbemerkt ueber vier Releases. Hinter einem Symlink gilt kein
|
|
10
|
+
* Versionsbereich (CR-GC-488 §1a) — eine Pruefung im ungelesenen Repo ist keine Pruefung.
|
|
11
|
+
*
|
|
12
|
+
* ## Was hier NICHT steht
|
|
13
|
+
*
|
|
14
|
+
* - **Abgeleitetes** — Titel, Severity, Meldung und `fix_hint` stehen an der Regeldefinition
|
|
15
|
+
* (`ALL_RULE_DEFS`), die Dimensions-/Phasenzuordnung in `readiness.ts`. Kein Wort davon wird
|
|
16
|
+
* hier wiederholt; ein zweiter Speicher derselben Wahrheit laeuft auseinander.
|
|
17
|
+
* - **`fix_hint` gegen `plain`/`se`** — `fix_hint` ist die Anweisung an den AGENTEN („Add a
|
|
18
|
+
* `verify` trace"), `plain`/`se` die Erklaerung fuer den MENSCHEN („was ist hier eigentlich
|
|
19
|
+
* kaputt, und wie heisst das in der SE-Literatur"). Verschiedene Leser, verschiedene Laenge,
|
|
20
|
+
* verschiedene Sprache — deshalb drei Felder und nicht eines.
|
|
21
|
+
* - **Nicht-Regel-Hilfe** — Dashboard-Panels, Artefakte, das Vokabular und die sechs
|
|
22
|
+
* Metrik-Dimensionen (`HELP_METRICS`, CR-GC-458) bleiben in graphcode: sie sind an dessen
|
|
23
|
+
* Oberflaeche gebunden, nicht an den Regelkatalog.
|
|
24
|
+
*
|
|
25
|
+
* ## Was die Version haelt
|
|
26
|
+
*
|
|
27
|
+
* **Die PRAESENZ ist Oberflaeche** und haengt an `RULES_VERSION`: eine Regel ohne Hilfeeintrag
|
|
28
|
+
* kann nicht landen, ein Eintrag ohne Regel auch nicht (`tests/unit/se-rule-help.test.ts`,
|
|
29
|
+
* beidseitig, gegen die lebenden Registraturen — nie gegen eine Handzaehlung).
|
|
30
|
+
* **Der TEXT ist es nicht.** „Prosa ist ein Patch-Bump, keine Grammatik" (CR-SM-244): ein
|
|
31
|
+
* umformulierter Satz darf keinen Major ausloesen, deshalb steht im Golden-File nur die
|
|
32
|
+
* Schluesselmenge, nicht die Prosa.
|
|
33
|
+
*
|
|
34
|
+
* Sprache: Englisch, wie die Regelbeschreibungen selbst. 18,6 KB reine Strings — der
|
|
35
|
+
* `./browser`-Eintrag bleibt transitiv `node:`-frei (CR-SM-230), Strings ziehen nichts nach.
|
|
36
|
+
*
|
|
37
|
+
* @author andreas@siglochconsulting
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* Je Regel-ID der Hilfeeintrag — Katalogregeln (`ALL_RULE_DEFS`) UND Conformance-Regeln
|
|
41
|
+
* (`CODE_CONFORMANCE_RULES`). Vollstaendig in beide Richtungen, erzwungen im Test.
|
|
42
|
+
*/
|
|
43
|
+
export const RULE_HELP = {
|
|
44
|
+
'AF-01': {
|
|
45
|
+
plain: "The operations concept was never stamped as written, so nobody can tell if it is current → run the ConOps step.",
|
|
46
|
+
se: "No `analysisFreshness.conops` stamp under `SYS.attributes` (CR-SM-227 presence rule; staleness is a consumer concern).",
|
|
47
|
+
prompt: "se-conops",
|
|
48
|
+
},
|
|
49
|
+
'AF-02': {
|
|
50
|
+
plain: "No trade study is on record, so the choices made were never written down → record the decision.",
|
|
51
|
+
se: "No `analysisFreshness.trade` stamp under `SYS.attributes`.",
|
|
52
|
+
prompt: "se-trade",
|
|
53
|
+
},
|
|
54
|
+
'AF-03': {
|
|
55
|
+
plain: "The assumptions behind this system were never reviewed → run the assumption review.",
|
|
56
|
+
se: "No `analysisFreshness.assumption-review` stamp under `SYS.attributes`.",
|
|
57
|
+
prompt: "se-irr",
|
|
58
|
+
},
|
|
59
|
+
'AF-04': {
|
|
60
|
+
plain: "No failure analysis is on record → run the FMEA.",
|
|
61
|
+
se: "No `analysisFreshness.fmea` stamp under `SYS.attributes`.",
|
|
62
|
+
prompt: "se-fmea",
|
|
63
|
+
},
|
|
64
|
+
'AF-05': {
|
|
65
|
+
plain: "No implementation plan is on record → derive the build order.",
|
|
66
|
+
se: "No `analysisFreshness.implplan` stamp under `SYS.attributes`.",
|
|
67
|
+
prompt: "se-plan",
|
|
68
|
+
},
|
|
69
|
+
'BQ-01': {
|
|
70
|
+
plain: "This requirement uses a vague word (\"appropriate\", \"fast\", \"user-friendly\") → two readers will build two different things. Replace it with the number or the condition you mean.",
|
|
71
|
+
se: "INCOSE quality: unambiguous. A weasel word in the `REQ` description — the rule names the word it found.",
|
|
72
|
+
prompt: "se:author-req",
|
|
73
|
+
},
|
|
74
|
+
'BQ-02': {
|
|
75
|
+
plain: "This requirement has nothing you could measure → nobody can tell whether it is met. Add the number, the limit or the observable condition.",
|
|
76
|
+
se: "INCOSE quality: verifiable. No measurable criterion in the `REQ` — the counterpart to R-01, which asks whether a test EXISTS; this one asks whether one COULD exist.",
|
|
77
|
+
prompt: "se:author-req",
|
|
78
|
+
},
|
|
79
|
+
'BQ-04': {
|
|
80
|
+
plain: "This requirement says almost the same as another one → decide which is the real one and merge or differentiate them.",
|
|
81
|
+
se: "INCOSE quality: necessary. Near-duplicate `REQ` pair by description similarity. NOTE: this rule is currently inert — it was written for pre-computed EMBEDDING similarity, which a pure contracts package cannot produce; a token-based substitute measured 0 findings across the family and 4950 on a templated fixture, both gate-7 outliers (CR-SM-286). Treated as an open grammar item, not a live check.",
|
|
82
|
+
},
|
|
83
|
+
'BQ-06': {
|
|
84
|
+
plain: "This requirement is not written in the agreed form (\"The system shall …\") → rewrite it that way, so every requirement reads the same.",
|
|
85
|
+
se: "INCOSE quality: conforming. The `REQ` description does not follow the \"System shall…\" pattern.",
|
|
86
|
+
prompt: "se:author-req",
|
|
87
|
+
},
|
|
88
|
+
'BQ-07': {
|
|
89
|
+
plain: "This requirement is missing a piece — who acts, on what, or under which condition → complete the sentence.",
|
|
90
|
+
se: "INCOSE quality: complete. The `REQ` lacks one of the required parts; the rule lists which.",
|
|
91
|
+
prompt: "se:author-req",
|
|
92
|
+
},
|
|
93
|
+
'BW-02': {
|
|
94
|
+
plain: "This block hands out many different kinds of data at its edge → whoever uses it has to understand all of them, so either bundle them or split the block.",
|
|
95
|
+
se: "Whitebox boundary width: distinct `SCHEMA` contracts on `FUNC` `io` `FLOW` `io` `FUNC` paths with one endpoint inside the `compose` subtree and one outside, judged against `metricPolicy.boundaryWidth.warning`. Parnas, information hiding — what a boundary HIDES is what makes it worth having. Rolled up over the subtree because a decomposed `FUNC` carries no `io` edges of its own (CR-SM-283).",
|
|
96
|
+
},
|
|
97
|
+
'CL-01': {
|
|
98
|
+
plain: "Someone only ever uses the system in one way, which usually means their other situations are missing → describe the scenarios you left out.",
|
|
99
|
+
se: "`ACTOR` whose `UC`s cover fewer than 2 distinct `operatingMode`s — a ConOps completeness signal.",
|
|
100
|
+
prompt: "se-conops",
|
|
101
|
+
},
|
|
102
|
+
'CR-01': {
|
|
103
|
+
plain: "Two parts exchange an unusually large amount of data, which usually means the boundary is in the wrong place → reconsider the cut.",
|
|
104
|
+
se: "High crossing `io` FLOW count between two `MOD`s — a coupling metric, advisory.",
|
|
105
|
+
},
|
|
106
|
+
'CR-R01': {
|
|
107
|
+
plain: "A change is recorded but says nothing about what it changes → link it to what it touches.",
|
|
108
|
+
se: "`CR` with no `relation` traces. It tracks nothing, so it is not traceable evidence.",
|
|
109
|
+
},
|
|
110
|
+
'CR-R02': {
|
|
111
|
+
plain: "A change is marked finished but there is no commit proving it → record the commit, or set it back to open.",
|
|
112
|
+
se: "`CR` with `status:done` and no `commitRef` attribute. This is the graph-vs-reality check for change history: \"done\" without evidence.",
|
|
113
|
+
},
|
|
114
|
+
'CR-R03': {
|
|
115
|
+
plain: "Several open changes touch the same thing, so they will collide → sequence them or merge them.",
|
|
116
|
+
se: "One element tracked by more than one `CR` with `status` open/in-progress.",
|
|
117
|
+
},
|
|
118
|
+
'FC-02': {
|
|
119
|
+
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
|
+
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.",
|
|
121
|
+
prompt: "se:author-uc",
|
|
122
|
+
},
|
|
123
|
+
'FC-03': {
|
|
124
|
+
plain: "A step inside a sequence contains further steps, so the sequence has hidden depth → lift them to the same level.",
|
|
125
|
+
se: "`FUNC` inside an `FCHAIN` that itself `compose`s other `FUNC`s. Chains are flat by construction.",
|
|
126
|
+
},
|
|
127
|
+
'FC-04': {
|
|
128
|
+
plain: "A sequence either has nobody starting it or nothing coming back out → wire both ends to whoever uses it.",
|
|
129
|
+
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
|
+
},
|
|
131
|
+
'FM-01': {
|
|
132
|
+
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: "Risk `REQ` missing `severity` / `occurrence` / `detection` attributes (AIAG-VDA).",
|
|
134
|
+
prompt: "se-fmea",
|
|
135
|
+
},
|
|
136
|
+
'FM-02': {
|
|
137
|
+
plain: "A known risk has nothing planned against it → write the countermeasure as its own requirement.",
|
|
138
|
+
se: "Risk `REQ` with no `compose`d mitigation `REQ` (`kinds:[\"mitigation\"]`).",
|
|
139
|
+
prompt: "se-fmea",
|
|
140
|
+
},
|
|
141
|
+
'FM-03': {
|
|
142
|
+
plain: "A high risk has no test that actually passed → add a test proving the countermeasure works.",
|
|
143
|
+
se: "Risk `REQ` with RPN > 100 and no `TEST` carrying `testResult:\"passed\"` verifying it.",
|
|
144
|
+
prompt: "se-fmea",
|
|
145
|
+
},
|
|
146
|
+
'IO-01': {
|
|
147
|
+
plain: "Two steps in the same sequence have no described data passing between them → add the data one hands to the other.",
|
|
148
|
+
se: "A `FUNC` pair inside one `FCHAIN` with no `io` path (`FUNC -io-> FLOW -io-> FUNC`) connecting them.",
|
|
149
|
+
},
|
|
150
|
+
'MS-01': {
|
|
151
|
+
plain: "A milestone has no work assigned to it → assign the work items that belong to it.",
|
|
152
|
+
se: "`MS` with no `CR` `relation`.",
|
|
153
|
+
},
|
|
154
|
+
'MS-02': {
|
|
155
|
+
plain: "A milestone waits on another milestone that doesn't exist → fix or remove the dependency.",
|
|
156
|
+
se: "`MS` `depends-on` relation targeting a missing `MS`.",
|
|
157
|
+
},
|
|
158
|
+
'MS-03': {
|
|
159
|
+
plain: "A change is not assigned to any milestone, so it has no place in the plan → assign it.",
|
|
160
|
+
se: "`CR` with no `relation` trace to an `MS`.",
|
|
161
|
+
prompt: "se-plan",
|
|
162
|
+
},
|
|
163
|
+
'MT-01': {
|
|
164
|
+
plain: "This module draws more from others than others draw from it → it will keep changing whenever they do. Measured, not judged: no threshold is set by default.",
|
|
165
|
+
se: "Instability I = fan_out / (fan_in + fan_out), counted in DISTINCT CONTRACTS crossing the module boundary — the same `moduleCrossings` definition CR-01, R-04 and BW-02 use (CR-SM-274/276). CR-SM-293 fixed both halves: it used to count every trace touching the module, of which only 34 % was coupling (`allocate` is module SIZE, `satisfy` is specification); and the direction was inverted — the CONSUMER depends, so supplying outward is fan_in (Martin's Ca) and drawing inward is fan_out (Ce). `metricPolicy.instability` defaults to `null`: the distribution is bimodal, so no threshold can be read from it. The number stays in every `graph_metrics` module row, next to `uphillDependencies` (CR-SM-301).",
|
|
166
|
+
},
|
|
167
|
+
'MT-02': {
|
|
168
|
+
plain: "The parts inside this module never talk to each other → it is really several modules in one.",
|
|
169
|
+
se: "LCOM4: the allocated `FUNC`s fall into that many disconnected groups. Connected means shared DATA: a common outgoing `io` target, or touching the same `FLOW` in either direction. CR-SM-297 dropped `satisfy` from that union — two FUNCs meeting the same requirement can be fully decoupled at runtime, and if they share one, the REQUIREMENT is what needs decomposing. `info` from `metricPolicy.lcom4.info`, `warning` from `.warning` (CR-GC-329).",
|
|
170
|
+
},
|
|
171
|
+
'ND-01': {
|
|
172
|
+
plain: "Two functions look like the same function written twice → merge them, or make clear what each one does differently.",
|
|
173
|
+
se: "Near-duplicate `FUNC` above 0.85 similarity (name, description and legal trace partners). Since CR-SM-286 the similarity is computed IN the rule, cached per graph — before that it had to be injected, and without injection the rule returned green, indistinguishable from \"no duplicates\".",
|
|
174
|
+
},
|
|
175
|
+
'ND-02': {
|
|
176
|
+
plain: "Two data contracts describe the same thing twice → merge them, or say what distinguishes them.",
|
|
177
|
+
se: "Near-duplicate `SCHEMA` above 0.85 similarity (name, description, fields and legal trace partners). Partners are filtered through `isValidTrace`: a rule must not reach its verdict via an edge R-18 rejects (CR-SM-286).",
|
|
178
|
+
},
|
|
179
|
+
'NFR-01': {
|
|
180
|
+
plain: "Something measured exceeds the limit that was set for it → fix it or change the limit deliberately.",
|
|
181
|
+
se: "Measured value above its declared budget on a `MOD` (physical) or `FUNC`/`FCHAIN` (behavioural).",
|
|
182
|
+
},
|
|
183
|
+
'R-01': {
|
|
184
|
+
plain: "A feature you've promised has no test proving it's met, so you can't show it works → add or author a test for it.",
|
|
185
|
+
se: "`REQ` with no incoming `verify` trace (test→requirement coverage, INCOSE V&V).",
|
|
186
|
+
prompt: "se:close-violations",
|
|
187
|
+
},
|
|
188
|
+
'R-02': {
|
|
189
|
+
plain: "A function isn't linked to any feature it's meant to build, so it may be dead code → link it to the feature it serves, or delete it.",
|
|
190
|
+
se: "`FUNC` with no `satisfy` trace to a `REQ` (design→requirement traceability).",
|
|
191
|
+
},
|
|
192
|
+
'R-04': {
|
|
193
|
+
plain: "A module does too much or is too tangled → open it and split it.",
|
|
194
|
+
se: "`MOD` with >12 `FUNC`, or 8–12 `FUNC` with >2 flows crossing the module boundary (cohesion/coupling).",
|
|
195
|
+
prompt: "se-view:arch",
|
|
196
|
+
},
|
|
197
|
+
'R-05': {
|
|
198
|
+
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 `REQ`.",
|
|
200
|
+
},
|
|
201
|
+
'R-08': {
|
|
202
|
+
plain: "A link points at something that no longer exists → repair or remove the broken link.",
|
|
203
|
+
se: "Trace whose source or target element is missing (dangling reference).",
|
|
204
|
+
},
|
|
205
|
+
'R-10': {
|
|
206
|
+
plain: "A piece of data goes nowhere — nothing produces or consumes it → connect it to a function or a person/outside system.",
|
|
207
|
+
se: "`FLOW` with no `io` trace to a `FUNC` or `ACTOR`.",
|
|
208
|
+
},
|
|
209
|
+
'R-12': {
|
|
210
|
+
plain: "Two items depend on each other in a loop, so neither can stand alone → remove or redirect one of the two links.",
|
|
211
|
+
se: "Direct cycle: A→B and B→A via the same trace type, checked on `compose` / `allocate` / `relation` only. Data (`io`) is exempt — a function that reads and writes the same `FLOW` is normal reuse, not a dependency cycle.",
|
|
212
|
+
},
|
|
213
|
+
'R-15': {
|
|
214
|
+
plain: "A sequence of steps for a use case is empty → add the functions that make it up.",
|
|
215
|
+
se: "`FCHAIN` with no `compose` to any `FUNC`.",
|
|
216
|
+
},
|
|
217
|
+
'R-16': {
|
|
218
|
+
plain: "A person or outside system isn't connected to anything → connect it to the data it sends or receives.",
|
|
219
|
+
se: "`ACTOR` with no `io` trace to a `FLOW`.",
|
|
220
|
+
},
|
|
221
|
+
'R-17': {
|
|
222
|
+
plain: "The top level of your project is empty — nothing is inside it → add the main use cases, features, or modules.",
|
|
223
|
+
se: "`SYS` with no `compose` to `UC` / `REQ` / `MOD`.",
|
|
224
|
+
},
|
|
225
|
+
'R-18': {
|
|
226
|
+
plain: "You connected two items in a combination that isn't allowed → use an allowed link, or fix what's at each end.",
|
|
227
|
+
se: "Trace whose (source-type, target-type) pair isn't an allowed combination in the metamodel of legal links.",
|
|
228
|
+
},
|
|
229
|
+
'R-19': {
|
|
230
|
+
plain: "A test that's meant to run doesn't point to a test file → add the link to the test file, or, if it isn't written yet, mark it not-yet-written.",
|
|
231
|
+
se: "Realized `TEST` with no valid `testRefs` `[{file, case?, tool}, …]` (at least one entry); else set `concept:true` (a stub).",
|
|
232
|
+
},
|
|
233
|
+
'R-20': {
|
|
234
|
+
plain: "A function is supposed to be built but doesn't point to its code → add the link to its code; or mark it not-built-yet / from-an-outside-library.",
|
|
235
|
+
se: "Realized `FUNC` with no valid `realRef` `{file, symbol}` (graph↔code binding); else `concept:true` / `external:true`.",
|
|
236
|
+
},
|
|
237
|
+
'R-21': {
|
|
238
|
+
plain: "You grouped functions into a chain that passes data along, but nothing tests that hand-off → add an integration test that checks the chain works.",
|
|
239
|
+
se: "FUNC↔FUNC connection (`FUNC` ─io→ `FLOW` ─io→ `FUNC`) whose endpoints DO share an `FCHAIN`, but no shared chain carries a verified integration test (`TEST` ─verify→ `REQ` ←satisfy─ `FCHAIN`). Pairs sharing no `FCHAIN` are silent: co-adjacency at a reused `FLOW` is not an asserted interface.",
|
|
240
|
+
},
|
|
241
|
+
'R-22': {
|
|
242
|
+
plain: "A function isn't assigned to any building block, so it has no home in the structure → put it on a module.",
|
|
243
|
+
se: "`FUNC` with no `allocate` trace to a `MOD` (deployment assignment); every function lives on exactly one module.",
|
|
244
|
+
},
|
|
245
|
+
'R-23': {
|
|
246
|
+
plain: "A building block is empty — no function is assigned to it → put a function on it, or remove the empty block.",
|
|
247
|
+
se: "`MOD` with no incoming `FUNC` ─allocate→ trace; the module-side complement of R-22 (empty-container signal like R-14/R-16/R-17).",
|
|
248
|
+
},
|
|
249
|
+
'R-26': {
|
|
250
|
+
plain: "A data format in the model isn't linked to the schema code that defines it → link it to the schema (or mark it concept/outside).",
|
|
251
|
+
se: "Realized `SCHEMA` with no valid `realRef` `{file, symbol}` (graph↔Zod binding); else `concept:true` / `external:true` (CR-211/228).",
|
|
252
|
+
},
|
|
253
|
+
'R-29': {
|
|
254
|
+
plain: "Two acceptances claim the same test file, so a red run cannot be traced to one of them and the gate counts that evidence twice → give the file to the one acceptance it really proves, or split it.",
|
|
255
|
+
se: "Test file exclusivity (CR-SM-231): every file in `attributes.testRefs` belongs to at most one `TEST`. An acceptance may name n files (1:n) — a file may not name n acceptances. Severity `error`, deliberately sharper than R-19/R-20: a doubly claimed file makes gate numbers wrong, which is a mis-measurement, not a completeness signal. Purely structural — the file need not exist to be claimed twice.",
|
|
256
|
+
},
|
|
257
|
+
'R-30': {
|
|
258
|
+
plain: "This function sits in no chain of effects, so nobody can say which use case it serves — and the checks that would prove its wiring never look at it → add it to the chain of the use case it belongs to.",
|
|
259
|
+
se: "FUNC belongs to a function chain (CR-GC-366): a `FUNC` needs an incoming `FCHAIN -compose-> FUNC`, directly or inherited from a parent `FUNC` it decomposes from. R-15 demanded the opposite direction — that a chain has functions — and nothing demanded that a function has a chain. That gap is load-bearing: IO-01 (FLOW paths between chain members) and R-21 (integration test per chain) both scope themselves to a chain, so a function outside every chain falls through both nets silently. Severity `warning`, not error: on a real model this fires on the majority of functions, and an error would block every further mutation through the delta gate.",
|
|
260
|
+
},
|
|
261
|
+
'R-31': {
|
|
262
|
+
plain: "This function has no input or no output, so it is a dead block in the picture — only an actor is allowed to be an end point → connect it to a flow on the missing side.",
|
|
263
|
+
se: "FUNC is wired (CR-GC-366): a `FUNC` needs at least one incoming `FLOW -io-> FUNC` and one outgoing `FUNC -io-> FLOW`. Only an `ACTOR` may terminate a chain. R-10 asks the same question from the FLOW side ('does this flow have a producer and a consumer?') and therefore never sees a function with no io edge at all — it does not appear in the FLOW loop. IO-01 presupposes chain membership and misses it too. One finding per FUNC naming the missing side(s), not one per side: otherwise the counter exceeds its own denominator contribution, the mis-measurement documented in CR-SM-242.",
|
|
264
|
+
},
|
|
265
|
+
'RC-01': {
|
|
266
|
+
plain: "A function points to code that isn't there anymore (file moved or name changed) → repoint it to the current code.",
|
|
267
|
+
se: "FUNC `realRef` that does not resolve: file missing on disk or symbol not declared in it (CR-GC-253 conformance over CodeFacts).",
|
|
268
|
+
},
|
|
269
|
+
'RC-02': {
|
|
270
|
+
plain: "A test points to a test file or test name that isn't there anymore → repoint it to the current test.",
|
|
271
|
+
se: "A `testRefs` entry that does not resolve: file missing or `case` not declared as an it/test/describe (CR-GC-253). The message names the concrete path — with n entries the node id alone is not actionable.",
|
|
272
|
+
},
|
|
273
|
+
'RC-03': {
|
|
274
|
+
plain: "A data format points to schema code that isn't there anymore (file moved or export renamed) → repoint it to the current schema.",
|
|
275
|
+
se: "SCHEMA `realRef` that does not resolve: file missing on disk or symbol not a declared export in it (CR-211/228 conformance over CodeFacts).",
|
|
276
|
+
},
|
|
277
|
+
'RC-04': {
|
|
278
|
+
plain: "A data format is defined but the function on that interface never actually checks incoming data against it → validate with it there.",
|
|
279
|
+
se: "Bound `SCHEMA` whose symbol is not imported+parsed (`.parse`/`.safeParse`) in any realized `FUNC` io-connected to it (CR-211); warn — the parse may sit in a framework layer.",
|
|
280
|
+
},
|
|
281
|
+
'RC-05': {
|
|
282
|
+
plain: "Code in one building block imports code in another, but the model never says those two are connected → draw the connection in the model, or drop the import.",
|
|
283
|
+
se: "File import crossing a `MOD` boundary with no documenting graph structure (no io/FLOW between the modules) — undocumented cross-module dependency (CR-212); warn indicator, not a blocker.",
|
|
284
|
+
},
|
|
285
|
+
'RC-06': {
|
|
286
|
+
plain: "This element points at code in a package your project does not actually install → either add the package, or point at the one that owns the symbol now.",
|
|
287
|
+
se: "An `external: true` `realRef` names a package that is in neither `dependencies` nor `devDependencies` of the consumer. Absent dependency data is SILENCE, not a violation — the extractor never looked, and treating that as \"declares nothing\" would report every external binding at once (CR-SM-262).",
|
|
288
|
+
},
|
|
289
|
+
'RD-01': {
|
|
290
|
+
plain: "A smallest-piece feature has nothing built to fulfil it → add what implements it.",
|
|
291
|
+
se: "Leaf `REQ` (no `compose`→`REQ` children) with no `satisfy` from a `FUNC`/`FCHAIN`/`MOD`/`SYS`.",
|
|
292
|
+
prompt: "se:close-violations",
|
|
293
|
+
},
|
|
294
|
+
'RD-02': {
|
|
295
|
+
plain: "You split a feature into smaller features but you're also building the big one directly → build only the small pieces, not both.",
|
|
296
|
+
se: "Parent `REQ` (has `compose`→`REQ` children) carrying a direct `FUNC` `satisfy`; the satisfy belongs on the children.",
|
|
297
|
+
},
|
|
298
|
+
'RD-03': {
|
|
299
|
+
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.",
|
|
300
|
+
se: "Parent `REQ` whose children all share one satisfier.",
|
|
301
|
+
},
|
|
302
|
+
'RD-04': {
|
|
303
|
+
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`/`MOD` `compose` `MOD`, and the root `FUNC` forest anchored at `SYS` (CR-SM-282). Default 9, the upper end of 7±2 (CR-SM-296). The `FUNC` `allocate` `MOD` leg moved to R-04 in that CR: counting allocated FUNCs is module SIZE, and one question deserves one rule.",
|
|
305
|
+
},
|
|
306
|
+
'SC-02': {
|
|
307
|
+
plain: "A data format is defined but nothing uses it → connect it to the data it describes, or drop it.",
|
|
308
|
+
se: "`SCHEMA` not referenced by any `FLOW` via a `relation` trace.",
|
|
309
|
+
},
|
|
310
|
+
'UC-01': {
|
|
311
|
+
plain: "A scenario says what someone wants to do but never says what the system must provide → write down the requirements it needs.",
|
|
312
|
+
se: "`UC` with no `compose` trace to any `REQ`. The use case carries no requirement content.",
|
|
313
|
+
prompt: "se:author-req",
|
|
314
|
+
},
|
|
315
|
+
'UC-02': {
|
|
316
|
+
plain: "A scenario has nobody who triggers it → name who or what starts it.",
|
|
317
|
+
se: "`UC` with no `ACTOR` connected by an `io` trace (directly or via a `FLOW` of its chain).",
|
|
318
|
+
prompt: "se:author-uc",
|
|
319
|
+
},
|
|
320
|
+
'UC-03': {
|
|
321
|
+
plain: "A scenario says what should be possible but not how it runs → describe the steps as a chain of functions.",
|
|
322
|
+
se: "`UC` with no `compose` trace to an `FCHAIN`. No behavioural scenario is declared.",
|
|
323
|
+
prompt: "se:author-uc",
|
|
324
|
+
},
|
|
325
|
+
'UC-04': {
|
|
326
|
+
plain: "A scenario has no real description, or still carries a placeholder like TBD → write what the user actually wants to achieve.",
|
|
327
|
+
se: "`UC` description shorter than 10 characters or containing TBD/TODO/FIXME/placeholder/XXX. Description IS the goal (CR-150).",
|
|
328
|
+
prompt: "se:author-uc",
|
|
329
|
+
},
|
|
330
|
+
'UC-05': {
|
|
331
|
+
plain: "A scenario does not say what must be true once it has finished → add that as a requirement.",
|
|
332
|
+
se: "`UC` with no `compose`d `REQ` carrying `kinds:[\"postcondition\"]`.",
|
|
333
|
+
},
|
|
334
|
+
'UC-06': {
|
|
335
|
+
plain: "A scenario does not say what must be true before it can start → add that as a requirement.",
|
|
336
|
+
se: "`UC` with no `compose`d `REQ` carrying `kinds:[\"precondition\"]`.",
|
|
337
|
+
},
|
|
338
|
+
'VR-01': {
|
|
339
|
+
plain: "A test exists but no result was ever recorded, so nobody knows if it passed → record the outcome.",
|
|
340
|
+
se: "`TEST` with no `testResult` attribute — assumed pending, never assumed green.",
|
|
341
|
+
},
|
|
342
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sigloch/contracts",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"grammar:snapshot": "SE_WRITE_GRAMMAR_SNAPSHOT=1 vitest run tests/unit/se-grammar-invariant.test.ts",
|
|
31
31
|
"prepublishOnly": "npm run build && npm run test",
|
|
32
32
|
"grammar:measure": "SE_MEASURE=1 vitest run tests/unit/se-grammar-measure.test.ts",
|
|
33
|
-
"report:silence": "node scripts/rules-silence-report.mjs"
|
|
33
|
+
"report:silence": "node scripts/rules-silence-report.mjs",
|
|
34
|
+
"report:bestand": "node scripts/bestand-report.mjs"
|
|
34
35
|
},
|
|
35
36
|
"dependencies": {
|
|
36
37
|
"zod": "^4.3.6"
|