@sigloch/contracts 10.9.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.
@@ -10,7 +10,7 @@ export function uc01HasRequirements(graph) {
10
10
  .filter(uc => !idx.out(uc.id, 'compose').some(t => idx.typeOf(t.target) === 'REQ'))
11
11
  .map(uc => ({
12
12
  rule_id: 'UC-01',
13
- severity: 'error',
13
+ severity: 'warning',
14
14
  element_id: uc.id,
15
15
  message: `${uc.id} has no requirements (compose→REQ)`,
16
16
  fix_hint: 'Add at least one REQ via compose trace',
@@ -67,7 +67,7 @@ export function uc02HasActor(graph) {
67
67
  .filter(uc => !idx.out(uc.id, 'compose').some(chain => idx.out(chain.target, 'compose').some(member => actorFacingFuncs.has(member.target))))
68
68
  .map(uc => ({
69
69
  rule_id: 'UC-02',
70
- severity: 'error',
70
+ severity: 'warning',
71
71
  element_id: uc.id,
72
72
  message: `${uc.id} is not reachable from any ACTOR`,
73
73
  fix_hint: 'Wire an ACTOR to a FLOW that feeds (or is fed by) a FUNC in one of this UC\'s function chains',
@@ -112,53 +112,15 @@ export function uc04GoalDefined(graph) {
112
112
  }));
113
113
  }
114
114
  // ---------------------------------------------------------------------------
115
- // UC-05: UC should have postcondition REQ (CR-165: compose only, satisfy UC→REQ invalid)
116
- // ---------------------------------------------------------------------------
117
- export function uc05HasPostcondition(graph) {
118
- const idx = indexOf(graph);
119
- return idx.elementsOfType('UC')
120
- .filter(uc => !idx.out(uc.id, 'compose').some(t => {
121
- const target = idx.byId.get(t.target);
122
- return target?.type === 'REQ' && target.kinds?.includes('postcondition');
123
- }))
124
- .map(uc => ({
125
- rule_id: 'UC-05',
126
- severity: 'info',
127
- element_id: uc.id,
128
- message: `${uc.id} has no postcondition requirement`,
129
- fix_hint: 'Add a REQ with kinds=["postcondition"] via compose trace',
130
- context: { element_type: uc.type, element_name: uc.name },
131
- }));
132
- }
133
- // ---------------------------------------------------------------------------
134
- // UC-06: UC should have precondition REQ (CR-165: compose only, satisfy UC→REQ invalid)
135
- // ---------------------------------------------------------------------------
136
- export function uc06HasPrecondition(graph) {
137
- const idx = indexOf(graph);
138
- return idx.elementsOfType('UC')
139
- .filter(uc => !idx.out(uc.id, 'compose').some(t => {
140
- const target = idx.byId.get(t.target);
141
- return target?.type === 'REQ' && target.kinds?.includes('precondition');
142
- }))
143
- .map(uc => ({
144
- rule_id: 'UC-06',
145
- severity: 'info',
146
- element_id: uc.id,
147
- message: `${uc.id} has no precondition requirement`,
148
- fix_hint: 'Add a REQ with kinds=["precondition"] via compose trace',
149
- context: { element_type: uc.type, element_name: uc.name },
150
- }));
151
- }
152
- // ---------------------------------------------------------------------------
153
115
  // Aggregated
154
116
  // ---------------------------------------------------------------------------
117
+ // CR-SM-357: UC-05/UC-06 (Pre-/Postcondition-REQ) sind gestrichen — Schreibregel in se:author-uc,
118
+ // wie BQ in author-req (CR-GC-602): sie feuerten an fast jedem UC, und niemand handelte darauf.
155
119
  export const UC_RULES = [
156
- { id: 'UC-01', name: 'UC has requirements', severity: 'error', evaluate: uc01HasRequirements, domain: ['UC'] },
157
- { id: 'UC-02', name: 'UC has actor', severity: 'error', evaluate: uc02HasActor, domain: ['UC'] },
120
+ { id: 'UC-01', name: 'UC has requirements', severity: 'warning', evaluate: uc01HasRequirements, domain: ['UC'] },
121
+ { id: 'UC-02', name: 'UC has actor', severity: 'warning', evaluate: uc02HasActor, domain: ['UC'] },
158
122
  { id: 'UC-03', name: 'UC has scenario', severity: 'warning', evaluate: uc03HasScenario, domain: ['UC'] },
159
123
  { id: 'UC-04', name: 'UC has goal', severity: 'warning', evaluate: uc04GoalDefined, domain: ['UC'] },
160
- { id: 'UC-05', name: 'UC has postcondition', severity: 'info', evaluate: uc05HasPostcondition, domain: ['UC'] },
161
- { id: 'UC-06', name: 'UC has precondition', severity: 'info', evaluate: uc06HasPrecondition, domain: ['UC'] },
162
124
  ];
163
125
  // CR-SM-236: `policy` wird durchgereicht, auch wo diese Familie heute keine Schwelle hat —
164
126
  // ein Sonderweg je Familie waere genau der zweite Pfad, den der Regelsatz verbietet.
@@ -3,7 +3,7 @@
3
3
  * VR-01: TEST with a testRefs entry that has no result (info).
4
4
  * CL-01: ACTOR without UCs in at least 2 distinct operatingModes (warning).
5
5
  */
6
- import { TestRefsSchema } from './ontology.js';
6
+ import { readTestRefs } from './ontology.js';
7
7
  // ---------------------------------------------------------------------------
8
8
  // VR-01: ein testRefs-Eintrag ohne Ergebnis
9
9
  //
@@ -20,17 +20,17 @@ export function vr01TestNoResult(graph) {
20
20
  for (const el of graph.elements) {
21
21
  if (el.type !== 'TEST')
22
22
  continue;
23
- const parsed = TestRefsSchema.safeParse(el.attributes?.testRefs);
24
- if (!parsed.success)
23
+ const parsed = readTestRefs(el.attributes);
24
+ if (parsed.state !== 'bound')
25
25
  continue; // keine/ungueltige Bindung → R-19-Gebiet
26
- const pending = parsed.data.filter(ref => ref.result === undefined);
26
+ const pending = parsed.value.filter(ref => ref.result === undefined);
27
27
  if (pending.length === 0)
28
28
  continue;
29
29
  violations.push({
30
30
  rule_id: 'VR-01',
31
31
  severity: 'info',
32
32
  element_id: el.id,
33
- message: `${el.id} has ${pending.length} of ${parsed.data.length} testRefs entries without a result — assumed pending: ${pending.map(r => r.file).join(', ')}`,
33
+ message: `${el.id} has ${pending.length} of ${parsed.value.length} testRefs entries without a result — assumed pending: ${pending.map(r => r.file).join(', ')}`,
34
34
  fix_hint: 'Record the run outcome on the entry (result, ranAt, evidence) — a binding without a result is not evidence',
35
35
  });
36
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sigloch/contracts",
3
- "version": "10.9.0",
3
+ "version": "10.12.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",