@sigloch/contracts 10.10.0 → 10.12.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.
@@ -24,6 +24,7 @@ export declare const FileFactsSchema: z.ZodObject<{
24
24
  testCases: z.ZodDefault<z.ZodArray<z.ZodString>>;
25
25
  importedSymbols: z.ZodDefault<z.ZodArray<z.ZodString>>;
26
26
  parsedSymbols: z.ZodDefault<z.ZodArray<z.ZodString>>;
27
+ zodSymbols: z.ZodOptional<z.ZodArray<z.ZodString>>;
27
28
  }, z.core.$strip>;
28
29
  export type FileFacts = z.infer<typeof FileFactsSchema>;
29
30
  /** One file→file import edge (repo-relative paths) — the module-drift evidence (CR-212). */
@@ -44,6 +45,7 @@ export declare const CodeFactsSchema: z.ZodObject<{
44
45
  testCases: z.ZodDefault<z.ZodArray<z.ZodString>>;
45
46
  importedSymbols: z.ZodDefault<z.ZodArray<z.ZodString>>;
46
47
  parsedSymbols: z.ZodDefault<z.ZodArray<z.ZodString>>;
48
+ zodSymbols: z.ZodOptional<z.ZodArray<z.ZodString>>;
47
49
  }, z.core.$strip>>;
48
50
  importEdges: z.ZodOptional<z.ZodArray<z.ZodObject<{
49
51
  from: z.ZodString;
@@ -54,6 +56,10 @@ export declare const CodeFactsSchema: z.ZodObject<{
54
56
  open: "open";
55
57
  done: "done";
56
58
  }>>>;
59
+ fileScope: z.ZodOptional<z.ZodEnum<{
60
+ all: "all";
61
+ referenced: "referenced";
62
+ }>>;
57
63
  }, z.core.$strip>;
58
64
  export type CodeFacts = z.infer<typeof CodeFactsSchema>;
59
65
  /** A conformance rule: pure over (graph, facts) — never touches I/O itself. */
@@ -103,7 +109,6 @@ export interface ImportCoverage {
103
109
  unassigned: string[];
104
110
  }
105
111
  export declare function importCoverage(graph: OntologyGraph, facts: CodeFacts): ImportCoverage;
106
- /** All RC conformance rules — evaluated by executors that can supply CodeFacts. */
107
112
  export declare const CODE_CONFORMANCE_RULES: ConformanceRuleDefinition[];
108
113
  /** Run all RC rules against a graph + extracted code facts. */
109
114
  export declare function evaluateConformanceRules(graph: OntologyGraph, facts: CodeFacts): RuleViolation[];
@@ -15,7 +15,7 @@
15
15
  * @sigloch/contracts/se — single source of truth for SE validation rules.
16
16
  */
17
17
  import { z } from 'zod/v4';
18
- import { RealRefSchema, TestRefsSchema } from './ontology.js';
18
+ import { readTestRefs, readRealRef } from './ontology.js';
19
19
  import { CLOSED_STATUS } from './cr-quality-rules.js';
20
20
  /** Parser facts about one source file (extracted by the executor). */
21
21
  export const FileFactsSchema = z.object({
@@ -29,6 +29,12 @@ export const FileFactsSchema = z.object({
29
29
  importedSymbols: z.array(z.string()).default([]),
30
30
  /** Symbols X invoked as `X.parse(` / `X.safeParse(` — the schema is actually used (CR-211). */
31
31
  parsedSymbols: z.array(z.string()).default([]),
32
+ /**
33
+ * Exported consts whose initializer is a Zod schema (`export const X = z.…`) — for RC-08
34
+ * (CR-SM-358). Optional, ABSENT = silence: the extractor did not look, which is not the
35
+ * same as "this file declares no schema" (same asymmetry as `declaredDependencies`).
36
+ */
37
+ zodSymbols: z.array(z.string()).optional(),
32
38
  });
33
39
  /** One file→file import edge (repo-relative paths) — the module-drift evidence (CR-212). */
34
40
  export const ImportEdgeSchema = z.object({
@@ -67,6 +73,13 @@ export const CodeFactsSchema = z.object({
67
73
  * `docs/cr/` was never looked at, it does not "have no CRs".
68
74
  */
69
75
  crFiles: z.record(z.string(), z.enum(['open', 'done'])).optional(),
76
+ /**
77
+ * Which files `files` covers (CR-SM-358): `referenced` = only files a realRef/testRefs
78
+ * entry names (the contract above), `all` = every source file of the repo. RC-09 asks
79
+ * "who ELSE parses this contract" and can only answer it over `all` — a partial scan
80
+ * would report the absence of what it never looked at. ABSENT = `referenced`.
81
+ */
82
+ fileScope: z.enum(['referenced', 'all']).optional(),
70
83
  });
71
84
  const missingFile = (facts, file) => facts.files[file]?.exists !== true;
72
85
  // RC-01: every valid FUNC realRef must resolve — file on disk, symbol declared in
@@ -81,10 +94,10 @@ function codeRefMustResolve(graph, facts) {
81
94
  continue;
82
95
  if (el.attributes?.concept === true || el.attributes?.external === true)
83
96
  continue;
84
- const parsed = RealRefSchema.safeParse(el.attributes?.realRef);
85
- if (!parsed.success)
97
+ const parsed = readRealRef(el.attributes);
98
+ if (parsed.state !== 'bound')
86
99
  continue; // no/invalid binding → R-20 territory
87
- const ref = parsed.data;
100
+ const ref = parsed.value;
88
101
  if (missingFile(facts, ref.file)) {
89
102
  violations.push({
90
103
  rule_id: 'RC-01',
@@ -125,10 +138,10 @@ function testRefMustResolve(graph, facts) {
125
138
  continue;
126
139
  if (el.attributes?.concept === true)
127
140
  continue;
128
- const parsed = TestRefsSchema.safeParse(el.attributes?.testRefs);
129
- if (!parsed.success)
141
+ const parsed = readTestRefs(el.attributes);
142
+ if (parsed.state !== 'bound')
130
143
  continue; // no/invalid binding → R-19 territory
131
- for (const ref of parsed.data) {
144
+ for (const ref of parsed.value) {
132
145
  if (missingFile(facts, ref.file)) {
133
146
  violations.push({
134
147
  rule_id: 'RC-02',
@@ -169,10 +182,10 @@ function schemaRefMustResolve(graph, facts) {
169
182
  continue;
170
183
  if (el.attributes?.concept === true || el.attributes?.external === true)
171
184
  continue;
172
- const parsed = RealRefSchema.safeParse(el.attributes?.realRef);
173
- if (!parsed.success)
185
+ const parsed = readRealRef(el.attributes);
186
+ if (parsed.state !== 'bound')
174
187
  continue; // no/invalid binding → R-26 territory
175
- const ref = parsed.data;
188
+ const ref = parsed.value;
176
189
  if (missingFile(facts, ref.file)) {
177
190
  violations.push({
178
191
  rule_id: 'RC-03',
@@ -199,6 +212,61 @@ function schemaRefMustResolve(graph, facts) {
199
212
  }
200
213
  return violations;
201
214
  }
215
+ // The files the MODEL names as a SCHEMA's interface: realRef files of the FUNCs io-connected
216
+ // (producer or consumer) to a FLOW whose data format is this SCHEMA (FUNC ─io→ FLOW
217
+ // ─relation→ SCHEMA), restricted to files that exist. RC-04 asks whether one of them parses
218
+ // the schema, RC-09 whether anyone ELSE does — one derivation, so both ask the same question.
219
+ function interfaceFiles(graph, schemaId, facts, typeOf) {
220
+ const flowIds = new Set(graph.traces
221
+ .filter(t => t.type === 'relation' && t.target === schemaId && typeOf.get(t.source) === 'FLOW')
222
+ .map(t => t.source));
223
+ if (flowIds.size === 0)
224
+ return [];
225
+ const funcIds = new Set(graph.traces
226
+ .filter(t => t.type === 'io' &&
227
+ ((flowIds.has(t.target) && typeOf.get(t.source) === 'FUNC') ||
228
+ (flowIds.has(t.source) && typeOf.get(t.target) === 'FUNC')))
229
+ .map(t => (flowIds.has(t.target) ? t.source : t.target)));
230
+ const files = [];
231
+ for (const fnId of funcIds) {
232
+ const fn = graph.elements.find(e => e.id === fnId);
233
+ const cr = readRealRef(fn?.attributes);
234
+ if (cr.state === 'bound' && !missingFile(facts, cr.value.file))
235
+ files.push(cr.value.file);
236
+ }
237
+ return files;
238
+ }
239
+ // Does `file` parse the schema? It must call `.parse`/`.safeParse` on the symbol AND have it in
240
+ // scope — imported, or declared right there: the definition file does not import its own schema
241
+ // (CR-SM-358, found by the positive control on graphcode's Format-E door, where the modelled
242
+ // translator lives in the schema's own file).
243
+ function parsesAt(facts, file, ref) {
244
+ const f = facts.files[file];
245
+ if (f?.exists !== true || !f.parsedSymbols.includes(ref.symbol))
246
+ return false;
247
+ return f.importedSymbols.includes(ref.symbol) || file === ref.file;
248
+ }
249
+ // Files outside `allowed` that import AND parse the symbol — the parsers the model does not
250
+ // name. Test files (testCases present) are exempt; consumer ratchets cover them. Empty unless
251
+ // the extractor saw every file (`fileScope: 'all'`): a partial scan cannot name who else parses.
252
+ function foreignParsers(facts, symbol, allowed) {
253
+ if (facts.fileScope !== 'all')
254
+ return [];
255
+ return Object.entries(facts.files)
256
+ .filter(([file, f]) => f.exists && !allowed.has(file) && f.testCases.length === 0 &&
257
+ f.importedSymbols.includes(symbol) && f.parsedSymbols.includes(symbol))
258
+ .map(([file]) => file)
259
+ .sort();
260
+ }
261
+ // A SCHEMA whose realRef symbol is declared but, by the extractor's own account, not a Zod
262
+ // schema. False when the extractor did not report `zodSymbols` (silence, not a verdict) or
263
+ // when the symbol is not declared at all (RC-03's finding, not this one).
264
+ function boundToNonZod(facts, ref) {
265
+ const f = facts.files[ref.file];
266
+ if (f?.exists !== true || f.zodSymbols === undefined)
267
+ return false;
268
+ return f.declaredSymbols.includes(ref.symbol) && !f.zodSymbols.includes(ref.symbol);
269
+ }
202
270
  // RC-04: a bound SCHEMA that the graph says is realized at an interface must
203
271
  // actually be parsed there (CR-211). The graph gives the check LOCATIONS: FUNCs
204
272
  // io-connected to a FLOW whose data format IS this SCHEMA (FUNC ─io→ FLOW
@@ -218,43 +286,29 @@ function schemaRefMustBeUsed(graph, facts) {
218
286
  continue;
219
287
  if (el.attributes?.concept === true)
220
288
  continue;
221
- const parsed = RealRefSchema.safeParse(el.attributes?.realRef);
222
- if (!parsed.success || parsed.data.symbol === undefined)
289
+ const parsed = readRealRef(el.attributes);
290
+ if (parsed.state !== 'bound' || parsed.value.symbol === undefined)
223
291
  continue;
224
- const ref = parsed.data;
225
- // The FLOWs whose data format is this SCHEMA (FLOW ─relation→ SCHEMA).
226
- const flowIds = new Set(graph.traces
227
- .filter(t => t.type === 'relation' && t.target === el.id && typeOf.get(t.source) === 'FLOW')
228
- .map(t => t.source));
229
- if (flowIds.size === 0)
230
- continue;
231
- // FUNCs io-connected to those FLOWs (producer or consumer).
232
- const funcIds = new Set(graph.traces
233
- .filter(t => t.type === 'io' &&
234
- ((flowIds.has(t.target) && typeOf.get(t.source) === 'FUNC') ||
235
- (flowIds.has(t.source) && typeOf.get(t.target) === 'FUNC')))
236
- .map(t => (flowIds.has(t.target) ? t.source : t.target)));
237
- // Realized FUNCs among them: a resolvable realRef whose file exists.
238
- const realizedFiles = [];
239
- for (const fnId of funcIds) {
240
- const fn = graph.elements.find(e => e.id === fnId);
241
- const cr = RealRefSchema.safeParse(fn?.attributes?.realRef);
242
- if (cr.success && !missingFile(facts, cr.data.file))
243
- realizedFiles.push(cr.data.file);
244
- }
292
+ const ref = parsed.value;
293
+ if (boundToNonZod(facts, ref))
294
+ continue; // RC-08 owns this cause (CR-SM-358)
295
+ const realizedFiles = interfaceFiles(graph, el.id, facts, typeOf);
245
296
  if (realizedFiles.length === 0)
246
297
  continue; // nothing realized to check against
247
- const usedSomewhere = realizedFiles.some(file => {
248
- const f = facts.files[file];
249
- return f.importedSymbols.includes(ref.symbol) && f.parsedSymbols.includes(ref.symbol);
250
- });
298
+ const usedSomewhere = realizedFiles.some(file => parsesAt(facts, file, ref));
251
299
  if (!usedSomewhere) {
300
+ // CR-SM-358: where it IS parsed, if the extractor saw every file — then the finding says
301
+ // where the binding has to point, and RC-09 stays quiet about the same cause.
302
+ const actual = foreignParsers(facts, ref.symbol, new Set([ref.file, ...realizedFiles]));
252
303
  violations.push({
253
304
  rule_id: 'RC-04',
254
305
  severity: 'warning',
255
306
  element_id: el.id,
256
- message: `${el.id} schema '${ref.symbol}' is not parsed in any realized FUNC at its modelled interface`,
257
- fix_hint: `Import and call ${ref.symbol}.parse()/.safeParse() in one of the io-connected FUNC's code files — or mark the SCHEMA concept:true if no code realizes it yet`,
307
+ message: `${el.id} schema '${ref.symbol}' is not parsed in any realized FUNC at its modelled interface` +
308
+ (actual.length > 0 ? ` — it is parsed in: ${actual.join(', ')}` : ''),
309
+ fix_hint: actual.length > 0
310
+ ? `The parse sits in ${actual.join(', ')}: point the FUNC realRef at that file, or move the parse into the modelled FUNC`
311
+ : `Import and call ${ref.symbol}.parse()/.safeParse() in one of the io-connected FUNC's code files — or mark the SCHEMA concept:true if no code realizes it yet`,
258
312
  context: { element_type: el.type, element_name: el.name },
259
313
  });
260
314
  }
@@ -295,12 +349,12 @@ function buildModResolver(graph) {
295
349
  for (const el of graph.elements) {
296
350
  if (el.type !== 'FUNC')
297
351
  continue;
298
- const cr = RealRefSchema.safeParse(el.attributes?.realRef);
299
- if (!cr.success)
352
+ const cr = readRealRef(el.attributes);
353
+ if (cr.state !== 'bound')
300
354
  continue;
301
355
  const modTrace = graph.traces.find(t => t.source === el.id && t.type === 'allocate' && typeOf.get(t.target) === 'MOD');
302
356
  if (modTrace)
303
- fileToMod.set(cr.data.file, modTrace.target);
357
+ fileToMod.set(cr.value.file, modTrace.target);
304
358
  }
305
359
  // MOD.path longest-prefix fallback for files with no direct binding.
306
360
  const modPaths = graph.elements
@@ -439,10 +493,10 @@ function externalRefMustNameDependency(graph, facts) {
439
493
  // `concept: true` has no binding that could rot — a concept node claims nothing about code.
440
494
  if (el.attributes?.external !== true || el.attributes?.concept === true)
441
495
  continue;
442
- const parsed = RealRefSchema.safeParse(el.attributes?.realRef);
443
- if (!parsed.success)
496
+ const parsed = readRealRef(el.attributes);
497
+ if (parsed.state !== 'bound')
444
498
  continue;
445
- const match = WORKSPACE_PATH.exec(parsed.data.file);
499
+ const match = WORKSPACE_PATH.exec(parsed.value.file);
446
500
  if (!match)
447
501
  continue; // not the shape this rule can decide
448
502
  const pkg = `${WORKSPACE_SCOPE}/${match[1]}`;
@@ -452,7 +506,7 @@ function externalRefMustNameDependency(graph, facts) {
452
506
  rule_id: 'RC-06',
453
507
  severity: 'warning',
454
508
  element_id: el.id,
455
- message: `${el.id} binds to '${parsed.data.file}', but '${pkg}' is not a declared dependency`,
509
+ message: `${el.id} binds to '${parsed.value.file}', but '${pkg}' is not a declared dependency`,
456
510
  fix_hint: `Add '${pkg}' to dependencies, or re-point the realRef at the package that now owns the symbol`,
457
511
  context: { element_type: el.type, element_name: el.name },
458
512
  });
@@ -514,6 +568,91 @@ function crNodeMatchesFile(graph, facts) {
514
568
  return violations;
515
569
  }
516
570
  /** All RC conformance rules — evaluated by executors that can supply CodeFacts. */
571
+ // ---------------------------------------------------------------------------
572
+ // RC-08 / RC-09 (CR-SM-358) — the contract has a checker, and only the modelled places use it.
573
+ //
574
+ // Why these two replace ND-01 in substance: parallel paths are not similar to each other
575
+ // (spike CR-GC-637: name similarity 0.000 in 7 of 7 documented pairs); they share a CONTRACT.
576
+ // A second translator of the same contract is found by asking who parses it, not what it
577
+ // looks like. RC-01..RC-07 ask model → code ("does the binding resolve?"); RC-09 is the
578
+ // first rule that asks code → model ("does the model know everyone who reads this?").
579
+ // ---------------------------------------------------------------------------
580
+ // RC-08: a bound SCHEMA must bind a Zod schema, not a type. A type is checked by the
581
+ // compiler and gone at runtime: whatever produces the data cannot prove it, and whoever
582
+ // reads it cannot check it. Data that nobody parses yet only has a reader nobody knows yet.
583
+ function schemaRefMustBeZod(graph, facts) {
584
+ const violations = [];
585
+ for (const el of graph.elements) {
586
+ if (el.type !== 'SCHEMA')
587
+ continue;
588
+ if (el.attributes?.concept === true)
589
+ continue;
590
+ const parsed = readRealRef(el.attributes);
591
+ if (parsed.state !== 'bound' || parsed.value.symbol === undefined)
592
+ continue;
593
+ const ref = parsed.value;
594
+ if (!boundToNonZod(facts, ref))
595
+ continue;
596
+ violations.push({
597
+ rule_id: 'RC-08',
598
+ severity: 'warning',
599
+ element_id: el.id,
600
+ message: `${el.id} realRef '${ref.symbol}' in '${ref.file}' is not a Zod schema — the contract cannot be checked at runtime`,
601
+ fix_hint: `Declare the contract as a Zod schema (export const ${ref.symbol}Schema = z.…) and bind the SCHEMA to it — a producer needs a checkable schema even while no reader is known`,
602
+ context: { element_type: el.type, element_name: el.name },
603
+ });
604
+ }
605
+ return violations;
606
+ }
607
+ // RC-09: a Zod-bound SCHEMA may be parsed only where the model says — in the realRef files
608
+ // of its producers/translators (the same set RC-04 checks) or in its own definition file.
609
+ // Any other file that imports AND parses the symbol is a translator the model does not
610
+ // know: a second path. The definition may live in another package (no facts entry) — only a
611
+ // proven type binding (RC-08) silences the rule. One finding per SCHEMA, listing the files — the count must not grow
612
+ // with usage (Gate 7, class CR-GC-315). Test files (testCases present) are exempt; ratchets
613
+ // in the consumer cover them. Runs only when the extractor saw every file (`fileScope:'all'`).
614
+ function schemaParsedOnlyAtInterface(graph, facts) {
615
+ if (facts.fileScope !== 'all')
616
+ return [];
617
+ // (foreignParsers repeats this guard; checking here skips the graph walk entirely.)
618
+ const typeOf = new Map(graph.elements.map(e => [e.id, e.type]));
619
+ const violations = [];
620
+ for (const el of graph.elements) {
621
+ if (el.type !== 'SCHEMA')
622
+ continue;
623
+ if (el.attributes?.concept === true)
624
+ continue;
625
+ const parsed = readRealRef(el.attributes);
626
+ if (parsed.state !== 'bound' || parsed.value.symbol === undefined)
627
+ continue;
628
+ const ref = parsed.value;
629
+ // Only a PROVEN type binding silences RC-09 (RC-08 owns it). A definition outside this
630
+ // repo — the family's shared contracts live in @sigloch/contracts — has no facts entry,
631
+ // and those are exactly the contracts reused most; a `.parse()` on the symbol is already
632
+ // the evidence that it is a runtime checker.
633
+ if (boundToNonZod(facts, ref))
634
+ continue;
635
+ const iface = interfaceFiles(graph, el.id, facts, typeOf);
636
+ // One cause, one finding (Gate 4): if the model names an interface and NONE of it parses,
637
+ // the parse merely sits elsewhere — that is RC-04's finding (which names the file), not a
638
+ // second path. A second path needs a first one: a modelled parser AND a foreign one.
639
+ const ifaceParses = iface.some(file => parsesAt(facts, file, ref));
640
+ if (iface.length > 0 && !ifaceParses)
641
+ continue;
642
+ const foreign = foreignParsers(facts, ref.symbol, new Set([ref.file, ...iface]));
643
+ if (foreign.length === 0)
644
+ continue;
645
+ violations.push({
646
+ rule_id: 'RC-09',
647
+ severity: 'warning',
648
+ element_id: el.id,
649
+ message: `${el.id} schema '${ref.symbol}' is parsed in ${foreign.length} file(s) the model does not know as its producer or translator: ${foreign.join(', ')}`,
650
+ fix_hint: 'Route the caller through the modelled translator — or, if it is a translator in its own right, model it: FUNC ─io→ FLOW ─relation→ this SCHEMA, with the FUNC realRef on that file',
651
+ context: { element_type: el.type, element_name: el.name },
652
+ });
653
+ }
654
+ return violations;
655
+ }
517
656
  export const CODE_CONFORMANCE_RULES = [
518
657
  { id: 'RC-01', name: 'FUNC realRef resolves to a declared symbol', severity: 'warning', domain: ['FUNC'], evaluate: codeRefMustResolve },
519
658
  { id: 'RC-02', name: 'testRefs entries resolve to runnable tests', severity: 'warning', domain: ['TEST'], evaluate: testRefMustResolve },
@@ -522,6 +661,8 @@ export const CODE_CONFORMANCE_RULES = [
522
661
  { id: 'RC-05', name: 'cross-module import drift', severity: 'warning', domain: ['MOD'], evaluate: importDriftConformance },
523
662
  { id: 'RC-06', name: 'external realRef names a declared dependency', severity: 'warning', domain: ['FUNC', 'MOD', 'SCHEMA'], evaluate: externalRefMustNameDependency },
524
663
  { id: 'RC-07', name: 'CR node agrees with docs/cr', severity: 'warning', domain: ['CR', 'SYS'], evaluate: crNodeMatchesFile },
664
+ { id: 'RC-08', name: 'SCHEMA realRef is a Zod schema', severity: 'warning', domain: ['SCHEMA'], evaluate: schemaRefMustBeZod },
665
+ { id: 'RC-09', name: 'SCHEMA is parsed only at its modelled interface', severity: 'warning', domain: ['SCHEMA'], evaluate: schemaParsedOnlyAtInterface },
525
666
  ];
526
667
  /** Run all RC rules against a graph + extracted code facts. */
527
668
  export function evaluateConformanceRules(graph, facts) {
@@ -8,6 +8,11 @@ import type { MetricPolicy } from './policy.js';
8
8
  /**
9
9
  * Abgeschlossen heisst: nicht mehr steuerbar. Alles andere ist Grundgesamtheit.
10
10
  * Exportiert fuer RC-07 (CR-SM-329), das dieselbe Frage gegen `docs/cr/done/` stellt.
11
+ *
12
+ * CR-SM-362 (ITEM-2026-536): nur noch `done`. Die Menge kannte `dropped`/`rejected`, der
13
+ * Element-Vertrag (`OntologyElement.status`) nicht — die Regeln rechneten mit Werten, die der
14
+ * Vertrag verbietet. Verworfen ist eine Begruendung im CR-Text, kein eigener Zustand: das
15
+ * Verzeichnis `done/` schliesst ihn, der Knoten spiegelt `done`.
11
16
  */
12
17
  export declare const CLOSED_STATUS: ReadonlySet<string>;
13
18
  export declare const CR_RULES: RuleDefinition[];
@@ -36,8 +36,13 @@ const SCOPE_TYPES = new Set(['FUNC', 'MOD', 'SCHEMA', 'REQ', 'UC']);
36
36
  /**
37
37
  * Abgeschlossen heisst: nicht mehr steuerbar. Alles andere ist Grundgesamtheit.
38
38
  * Exportiert fuer RC-07 (CR-SM-329), das dieselbe Frage gegen `docs/cr/done/` stellt.
39
+ *
40
+ * CR-SM-362 (ITEM-2026-536): nur noch `done`. Die Menge kannte `dropped`/`rejected`, der
41
+ * Element-Vertrag (`OntologyElement.status`) nicht — die Regeln rechneten mit Werten, die der
42
+ * Vertrag verbietet. Verworfen ist eine Begruendung im CR-Text, kein eigener Zustand: das
43
+ * Verzeichnis `done/` schliesst ihn, der Knoten spiegelt `done`.
39
44
  */
40
- export const CLOSED_STATUS = new Set(['done', 'dropped', 'rejected']);
45
+ export const CLOSED_STATUS = new Set(['done']);
41
46
  function crMustTrack(graph) {
42
47
  const typeOf = new Map(graph.elements.map(e => [e.id, e.type]));
43
48
  const crs = graph.elements.filter(e => {
@@ -7,7 +7,7 @@
7
7
  * by dimension nature: physical budgets (weight/power/cost) live on the part
8
8
  * (MOD); behavioral budgets (timing/memory-throughput) on the FCHAIN/FUNC.
9
9
  */
10
- import { TestRefsSchema } from './ontology.js';
10
+ import { readTestRefs } from './ontology.js';
11
11
  import { actionPriority, apMethod } from './action-priority.js';
12
12
  const PHYSICAL_BUDGET_PAIRS = [
13
13
  ['costBudget', 'measuredCost', 'cost'],
@@ -106,10 +106,10 @@ export function fm03HighRiskUnverified(graph, policy) {
106
106
  graph.elements.some(el => {
107
107
  if (el.id !== t.source || el.type !== 'TEST')
108
108
  return false;
109
- const parsed = TestRefsSchema.safeParse(el.attributes?.testRefs);
110
- if (!parsed.success)
109
+ const parsed = readTestRefs(el.attributes);
110
+ if (parsed.state !== 'bound')
111
111
  return false; // keine Bindung → keine Evidenz
112
- return parsed.data.every(ref => ref.result === 'passed');
112
+ return parsed.value.every(ref => ref.result === 'passed');
113
113
  }));
114
114
  return !hasPassedTest;
115
115
  })
@@ -41,30 +41,16 @@
41
41
  *
42
42
  * @author andreas@siglochconsulting
43
43
  */
44
+ import { z } from 'zod/v4';
44
45
  import type { OntologyGraph } from './ontology.js';
45
46
  /** Eine Zeile je FUNC — mit Schwelle oder ohne, wie `ModuleMetrics` je MOD (CR-SM-232). */
46
- export interface FunctionCriticality {
47
- funcId: string;
48
- funcName: string;
49
- /**
50
- * Wirkketten, die diese FUNC komponieren — R-30s Definition: direkte
51
- * `FCHAIN -compose-> FUNC`-Kante, keine Vererbung ueber Vorfahren.
52
- *
53
- * `0` ist eine AUSSAGE, kein fehlender Wert: bei einem Blatt ist es R-30s Befund, bei einem
54
- * zerlegten Block der von FC-03 erzwungene Normalzustand. Wer die beiden unterscheiden muss,
55
- * fragt `decomposedFuncs()` — diese Datei tut es bewusst nicht (sie waere sonst an `rules.ts`
56
- * gebunden und fuer `rules.ts` nicht mehr importierbar).
57
- */
58
- chains: number;
59
- /**
60
- * Use Cases, die ueber diese Ketten an der FUNC haengen (`UC -compose-> FCHAIN`).
61
- *
62
- * Nicht aus `chains` ableitbar und auch nicht dasselbe: eine FUNC in drei Ketten EINES Use
63
- * Case ist etwas anderes als eine in drei Ketten dreier Use Cases. Gemessen an graphcode
64
- * faellt die Zahl regelmaessig kleiner aus als `chains` (FUNC-mutate: 11 Ketten, 7 UCs).
65
- */
66
- useCases: number;
67
- }
47
+ export declare const FunctionCriticality: z.ZodObject<{
48
+ funcId: z.ZodString;
49
+ funcName: z.ZodString;
50
+ chains: z.ZodNumber;
51
+ useCases: z.ZodNumber;
52
+ }, z.core.$strip>;
53
+ export type FunctionCriticality = z.infer<typeof FunctionCriticality>;
68
54
  /**
69
55
  * Kritikalitaet je FUNC, kritischste zuerst.
70
56
  *
@@ -1,4 +1,72 @@
1
+ /**
2
+ * CR-SM-314 — wie kritisch ist eine Funktion? Ketten und Use Cases, als ZAHL.
3
+ *
4
+ * Die Frage stammt aus dem Betrieb und hat drei Abnehmer, die bis hierher jeder fuer sich
5
+ * geraten haben: **Blast Radius** einer Aenderung, **Kritikalitaet** einer Funktion,
6
+ * **Rollout-Reihenfolge**. Alle drei fragen dasselbe: an wie vielen Wirkketten haengt dieses
7
+ * Stueck, und wie viele Use Cases stehen dahinter.
8
+ *
9
+ * ## Die Definition ist GELIEHEN, nicht neu
10
+ *
11
+ * "Eine FUNC ist in einer Kette" heisst hier woertlich, was R-30 darunter versteht: eine
12
+ * direkte `FCHAIN -compose-> FUNC`-Kante. Keine Vererbung ueber compose-Vorfahren.
13
+ *
14
+ * Der Rollup wurde GEMESSEN und VERWORFEN: ueber 17 Familiengraphen haetten Vorfahren-Ketten
15
+ * die Grundgesamtheit von 224 auf 227 FUNCs gehoben — drei Stueck. Er kauft nichts und waere
16
+ * eine ZWEITE Vorstellung davon, wozu eine Funktion gehoert, neben R-30s. Genau die Drift, gegen
17
+ * die `module-crossings.ts` gebaut wurde (CR-SM-276). Ein zerlegter Block misst deshalb 0, und
18
+ * das ist richtig: FC-03 verbietet ein Kettenglied mit verschachtelter Zerlegung, ein Block KANN
19
+ * die Kante gar nicht tragen.
20
+ *
21
+ * ## Diese Datei URTEILT NICHT
22
+ *
23
+ * Kein `infrastructure`-Flag, keine Schwelle, keine Severity. Ein Flag waere ein Urteil in der
24
+ * MESSUNG, und die Schwelle gehoert in `MetricPolicy` (`criticality.infrastructure`) — dieselbe
25
+ * Trennung, die `moduleMetrics` gegen MT-01/MT-02 haelt: die Zahl steht in jeder Zeile, ob eine
26
+ * Regel sie liest oder nicht.
27
+ *
28
+ * ## Warum sie nur `ontology` und `graph-index` importiert
29
+ *
30
+ * Damit `rules.ts` sie konsumieren darf. R-21 braucht dieselbe Kettenzahl fuer seine
31
+ * Infrastruktur-Ausnahme (CR-SM-313); rechnete die Regel sie selbst, haetten wir zwei
32
+ * Kettenbegriffe im selben Paket. EINE Rechnung, ZWEI Abnehmer — Vorbild `module-crossings.ts`,
33
+ * das aus demselben Grund keinen Regelcode importiert.
34
+ *
35
+ * ## Gemessen (17 Familiengraphen, 2026-09-12)
36
+ *
37
+ * 278 FUNCs liegen in mindestens einer Kette: 224 in genau einer, 37 in zwei, 6 in drei, 8 in
38
+ * vier, je eine in fuenf, sechs und elf. Ein duenner Schwanz ohne Plateau — aus der FORM dieser
39
+ * Verteilung ist keine Schwelle abzulesen (derselbe Befund wie bei `instability`, CR-SM-293).
40
+ * Ablesbar ist sie an ihrer WIRKUNG, und das steht bei `criticality` in der Policy.
41
+ *
42
+ * @author andreas@siglochconsulting
43
+ */
44
+ import { z } from 'zod/v4';
1
45
  import { indexOf } from './graph-index.js';
46
+ /** Eine Zeile je FUNC — mit Schwelle oder ohne, wie `ModuleMetrics` je MOD (CR-SM-232). */
47
+ // CR-SM-361: ein Zod-Vertrag, kein Typ — `functionCriticality` prueft seine Ausgabe.
48
+ export const FunctionCriticality = z.object({
49
+ funcId: z.string(),
50
+ funcName: z.string(),
51
+ /**
52
+ * Wirkketten, die diese FUNC komponieren — R-30s Definition: direkte
53
+ * `FCHAIN -compose-> FUNC`-Kante, keine Vererbung ueber Vorfahren.
54
+ *
55
+ * `0` ist eine AUSSAGE, kein fehlender Wert: bei einem Blatt ist es R-30s Befund, bei einem
56
+ * zerlegten Block der von FC-03 erzwungene Normalzustand. Wer die beiden unterscheiden muss,
57
+ * fragt `decomposedFuncs()` — diese Datei tut es bewusst nicht (sie waere sonst an `rules.ts`
58
+ * gebunden und fuer `rules.ts` nicht mehr importierbar).
59
+ */
60
+ chains: z.number().int().nonnegative(),
61
+ /**
62
+ * Use Cases, die ueber diese Ketten an der FUNC haengen (`UC -compose-> FCHAIN`).
63
+ *
64
+ * Nicht aus `chains` ableitbar und auch nicht dasselbe: eine FUNC in drei Ketten EINES Use
65
+ * Case ist etwas anderes als eine in drei Ketten dreier Use Cases. Gemessen an graphcode
66
+ * faellt die Zahl regelmaessig kleiner aus als `chains` (FUNC-mutate: 11 Ketten, 7 UCs).
67
+ */
68
+ useCases: z.number().int().nonnegative(),
69
+ });
2
70
  /**
3
71
  * Kritikalitaet je FUNC, kritischste zuerst.
4
72
  *
@@ -65,7 +133,9 @@ export function functionCriticality(graph) {
65
133
  ucs.add(uc);
66
134
  return { funcId: fn.id, funcName: fn.name, chains: chains.size, useCases: ucs.size };
67
135
  });
68
- return rows.sort((a, b) => b.chains - a.chains ||
136
+ const sorted = rows.sort((a, b) => b.chains - a.chains ||
69
137
  b.useCases - a.useCases ||
70
138
  (a.funcId < b.funcId ? -1 : a.funcId > b.funcId ? 1 : 0));
139
+ z.array(FunctionCriticality).parse(sorted); // CR-SM-361: der Erzeuger prueft seinen Vertrag
140
+ return sorted;
71
141
  }
@@ -13,16 +13,16 @@ export declare const GRAMMAR_SNAPSHOT: {
13
13
  readonly versions: {
14
14
  readonly ontology: "9.1.0";
15
15
  readonly metaModel: "5.2.0";
16
- readonly rules: "31.0.0";
16
+ readonly rules: "33.0.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-> SCHEMA", "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", "TEST -verify-> SCHEMA", "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 (warning) domain=[CR]", "CR-R02 (warning) 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 (warning) domain=[REQ]", "IO-01 (warning) domain=[FUNC]", "IO-02 (error) domain=[FLOW]", "IR-01 (warning) domain=[graph]", "MS-01 (warning) domain=[MS]", "MS-02 (warning) domain=[MS]", "MS-03 (info) domain=[CR]", "MT-01 (warning) domain=[MOD]", "MT-02 (info) domain=[MOD]", "MT-04 (info) domain=[FUNC]", "ND-01 (warning) domain=[FUNC]", "ND-02 (warning) 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,FUNC]", "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]", "R-32 (warning) domain=[SCHEMA]", "RC-01 (warning) domain=[FUNC]", "RC-02 (warning) domain=[TEST]", "RC-03 (warning) domain=[SCHEMA]", "RC-04 (warning) domain=[SCHEMA]", "RC-05 (warning) domain=[MOD]", "RC-06 (warning) domain=[FUNC,MOD,SCHEMA]", "RC-07 (warning) domain=[CR,SYS]", "RD-01 (warning) domain=[REQ]", "RD-02 (warning) domain=[REQ]", "RD-03 (info) domain=[REQ]", "RD-04 (warning) domain=[FUNC,MOD,SYS]", "RD-05 (warning) domain=[FUNC,MOD,SYS]", "SC-02 (warning) domain=[SCHEMA]", "TR-01 (warning) domain=[graph]", "UC-01 (warning) domain=[UC]", "UC-02 (warning) 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
- readonly conformanceRules: readonly ["RC-01 (warning)", "RC-02 (warning)", "RC-03 (warning)", "RC-04 (warning)", "RC-05 (warning)", "RC-06 (warning)", "RC-07 (warning)"];
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 (warning) domain=[CR]", "CR-R02 (warning) 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 (warning) domain=[REQ]", "IO-01 (warning) domain=[FUNC]", "IO-02 (error) domain=[FLOW]", "IR-01 (warning) domain=[graph]", "MS-01 (warning) domain=[MS]", "MS-02 (warning) domain=[MS]", "MS-03 (info) domain=[CR]", "MT-01 (warning) domain=[MOD]", "MT-02 (warning) domain=[MOD]", "MT-04 (info) domain=[FUNC]", "ND-01 (warning) domain=[FUNC]", "ND-02 (warning) 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,FUNC]", "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]", "R-32 (warning) domain=[SCHEMA]", "RC-01 (warning) domain=[FUNC]", "RC-02 (warning) domain=[TEST]", "RC-03 (warning) domain=[SCHEMA]", "RC-04 (warning) domain=[SCHEMA]", "RC-05 (warning) domain=[MOD]", "RC-06 (warning) domain=[FUNC,MOD,SCHEMA]", "RC-07 (warning) domain=[CR,SYS]", "RC-08 (warning) domain=[SCHEMA]", "RC-09 (warning) domain=[SCHEMA]", "RD-01 (warning) domain=[REQ]", "RD-02 (warning) domain=[REQ]", "RD-04 (warning) domain=[FUNC,MOD,SYS]", "RD-05 (warning) domain=[FUNC,MOD,SYS]", "SC-02 (warning) domain=[SCHEMA]", "TR-01 (warning) domain=[graph]", "UC-01 (warning) domain=[UC]", "UC-02 (warning) domain=[UC]", "UC-03 (warning) domain=[UC]", "UC-04 (warning) domain=[UC]", "VR-01 (info) domain=[TEST]"];
24
+ readonly conformanceRules: readonly ["RC-01 (warning)", "RC-02 (warning)", "RC-03 (warning)", "RC-04 (warning)", "RC-05 (warning)", "RC-06 (warning)", "RC-07 (warning)", "RC-08 (warning)", "RC-09 (warning)"];
25
25
  readonly policy: readonly ["apTable = null", "boundaryWidth = {warning:5}", "criticality = {infrastructure:3}", "crossingFlows = {warning:3}", "decompositionBreadth = {min:3,warning:9}", "instability = null", "lcom4 = {info:4,warning:6}", "riskRpn = 100"];
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", "IO-02", "IR-01", "MS-01", "MS-02", "MS-03", "MT-01", "MT-02", "MT-04", "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", "R-32", "RC-01", "RC-02", "RC-03", "RC-04", "RC-05", "RC-06", "RC-07", "RD-01", "RD-02", "RD-03", "RD-04", "RD-05", "SC-02", "TR-01", "UC-01", "UC-02", "UC-03", "UC-04", "UC-05", "UC-06", "VR-01"];
27
- readonly exports: readonly ["ACCEPTED_FINDINGS_ATTRIBUTE", "AF_RULES", "ALL_RULE_DEFS", "AO_RULES", "AcceptedFindingSchema", "ActionPriority", "AnalysisArtifactId", "AnalysisFreshnessStampSchema", "ApTableSchema", "BOUNDED_PATTERNS", "BQ_RULES", "CLOSED_STATUS", "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_TASKS", "RULE_TO_DIMENSION", "RULE_TO_PHASE", "ReadinessDimension", "ReadinessReport", "ReadinessScore", "RealRefSchema", "RepoRelativePathSchema", "ReqKind", "RuleSeverity", "RuleViolation", "SC_RULES", "SteerSpace", "SteerTerm", "TASK_ENTRY", "TASK_OUTCOME_RULES", "TASK_OWNED_RULES", "TRACE_PATTERNS", "TestRefSchema", "TestRefsSchema", "TestResult", "Trace", "TraceType", "UC_RULES", "V3_RULES", "VIEW_RULES", "VerificationMethod", "ViolationCandidate", "ViolationContext", "acceptedRuleIds", "actionPriority", "admittingAlternatives", "allocationCohesion", "apMethod", "assumptionReviewPromoted", "attributeTypeOf", "boxContracts", "bq01Unambiguous", "bq02Verifiable", "bq04Necessary", "bq06Conforming", "bq07Complete", "bw02WhiteboxWidth", "chainsByFunc", "cl01ConopsCompleteness", "cr01CrossingFlowCount", "crossingContractCount", "decomposedFuncs", "evaluateAFRules", "evaluateAORules", "evaluateAllRules", "evaluateBQRules", "evaluateCRRules", "evaluateConformanceRules", "evaluateFCRules", "evaluateFMRules", "evaluateMTRules", "evaluateNDRules", "evaluateRules", "evaluateSCRules", "evaluateTaskOutcomeRules", "evaluateUCRules", "evaluateViewRules", "extractFormatE", "fc02LeafUcHasFchain", "fc03FchainFlat", "fc04ActorBounded", "flowProducers", "fm01MissingFmeaAttributes", "fm02MissingMitigation", "fm03HighRiskUnverified", "funcSimilarity", "funcSubtree", "functionCriticality", "getRuleDefsForProfile", "hydrateAttrValue", "importCoverage", "indexOf", "io01CrossModuleCompleteness", "isElementUid", "isValidTrace", "jaccard", "maxOccurs", "minOccurs", "moduleCrossings", "moduleMetrics", "mt01Instability", "mt02Lcom4", "mt04WhiteboxLcom4", "nd01FuncNearDuplicate", "nd02SchemaNearDuplicate", "nfr01BudgetOvershoot", "normalizeReqKinds", "pairsAbove", "parseElementUid", "sc02IsReferenced", "schemaSimilarity", "setBQ04SimilarityMatrix", "subtreeFuncs", "taskOf", "toElementUid", "toEvaluableGraph", "tokens", "traceRejection", "tradeDecisionRecorded", "tryParseElementUid", "uc01HasRequirements", "uc02HasActor", "uc03HasScenario", "uc04GoalDefined", "uc05HasPostcondition", "uc06HasPrecondition", "vr01TestNoResult", "whiteboxContractCount"];
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", "IO-02", "IR-01", "MS-01", "MS-02", "MS-03", "MT-01", "MT-02", "MT-04", "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", "R-32", "RC-01", "RC-02", "RC-03", "RC-04", "RC-05", "RC-06", "RC-07", "RC-08", "RC-09", "RD-01", "RD-02", "RD-04", "RD-05", "SC-02", "TR-01", "UC-01", "UC-02", "UC-03", "UC-04", "VR-01"];
27
+ readonly exports: readonly ["ACCEPTED_FINDINGS_ATTRIBUTE", "AF_RULES", "ALL_RULE_DEFS", "AO_RULES", "AcceptedFindingSchema", "ActionPriority", "AnalysisArtifactId", "AnalysisFreshnessStampSchema", "ApTableSchema", "BOUNDED_PATTERNS", "BQ_RULES", "CLOSED_STATUS", "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", "FunctionCriticality", "ImportEdgeSchema", "MAX_SLUG_LENGTH", "META_MODEL_VERSION", "MODELING_ELEMENT_TYPES", "MT_RULES", "MetricPolicySchema", "ModuleMetrics", "ND_RULES", "ONTOLOGY_VERSION", "OntologyElement", "OntologyGraph", "PHASE_READINESS_NAME", "PhaseGate", "READINESS_SCORED_PROFILES", "REQUIRED_PATTERNS", "RULES_VERSION", "RULE_HELP", "RULE_TASKS", "RULE_TO_DIMENSION", "RULE_TO_PHASE", "ReadinessDimension", "ReadinessReport", "ReadinessScore", "RealRefSchema", "RepoRelativePathSchema", "ReqKind", "RuleSeverity", "RuleViolation", "SC_RULES", "SteerSpace", "SteerTerm", "TASK_ENTRY", "TASK_OUTCOME_RULES", "TASK_OWNED_RULES", "TRACE_PATTERNS", "TestRefSchema", "TestRefsSchema", "TestResult", "Trace", "TraceType", "UC_RULES", "V3_RULES", "VIEW_RULES", "VerificationMethod", "ViolationCandidate", "ViolationContext", "acceptedRuleIds", "actionPriority", "admittingAlternatives", "allocationCohesion", "apMethod", "assumptionReviewPromoted", "attributeTypeOf", "boxContracts", "bq01Unambiguous", "bq02Verifiable", "bq04Necessary", "bq06Conforming", "bq07Complete", "bw02WhiteboxWidth", "chainsByFunc", "cl01ConopsCompleteness", "cr01CrossingFlowCount", "crossingContractCount", "decomposedFuncs", "evaluateAFRules", "evaluateAORules", "evaluateAllRules", "evaluateBQRules", "evaluateCRRules", "evaluateConformanceRules", "evaluateFCRules", "evaluateFMRules", "evaluateMTRules", "evaluateNDRules", "evaluateRules", "evaluateSCRules", "evaluateTaskOutcomeRules", "evaluateUCRules", "evaluateViewRules", "extractFormatE", "fc02LeafUcHasFchain", "fc03FchainFlat", "fc04ActorBounded", "flowProducers", "fm01MissingFmeaAttributes", "fm02MissingMitigation", "fm03HighRiskUnverified", "funcSimilarity", "funcSubtree", "functionCriticality", "getRuleDefsForProfile", "hydrateAttrValue", "importCoverage", "indexOf", "io01CrossModuleCompleteness", "isElementUid", "isValidTrace", "jaccard", "maxOccurs", "minOccurs", "moduleCrossings", "moduleMetrics", "mt01Instability", "mt02Lcom4", "mt04WhiteboxLcom4", "nd01FuncNearDuplicate", "nd02SchemaNearDuplicate", "nfr01BudgetOvershoot", "normalizeReqKinds", "pairsAbove", "parseElementUid", "readRealRef", "readTestRefs", "sc02IsReferenced", "schemaSimilarity", "setBQ04SimilarityMatrix", "subtreeFuncs", "taskOf", "toElementUid", "toEvaluableGraph", "tokens", "traceRejection", "tradeDecisionRecorded", "tryParseElementUid", "uc01HasRequirements", "uc02HasActor", "uc03HasScenario", "uc04GoalDefined", "vr01TestNoResult", "whiteboxContractCount"];
28
28
  };