@3f-consulting/spec-controller-core 0.1.0-alpha.6 → 0.1.0-alpha.61

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.
Files changed (249) hide show
  1. package/README.md +3 -3
  2. package/dist/assemble/evidenceReconciliationFromSources.d.ts +5 -40
  3. package/dist/assemble/evidenceReconciliationFromSources.d.ts.map +1 -1
  4. package/dist/assemble/evidenceReconciliationFromSources.js +29 -324
  5. package/dist/assemble/evidenceReconciliationFromSources.js.map +1 -1
  6. package/dist/assemble/renderInput.d.ts +6 -72
  7. package/dist/assemble/renderInput.d.ts.map +1 -1
  8. package/dist/assemble/renderInput.js +3 -45
  9. package/dist/assemble/renderInput.js.map +1 -1
  10. package/dist/census/evidenceObligations.d.ts +10 -46
  11. package/dist/census/evidenceObligations.d.ts.map +1 -1
  12. package/dist/census/evidenceObligations.js +15 -25
  13. package/dist/census/evidenceObligations.js.map +1 -1
  14. package/dist/domain/evidenceOrder.d.ts +3 -0
  15. package/dist/domain/evidenceOrder.d.ts.map +1 -0
  16. package/dist/domain/evidenceOrder.js +15 -0
  17. package/dist/domain/evidenceOrder.js.map +1 -0
  18. package/dist/domain/evidenceReconciliation.d.ts +16 -386
  19. package/dist/domain/evidenceReconciliation.d.ts.map +1 -1
  20. package/dist/domain/evidenceReconciliation.js +79 -375
  21. package/dist/domain/evidenceReconciliation.js.map +1 -1
  22. package/dist/domain/featureCode.d.ts +4 -0
  23. package/dist/domain/featureCode.d.ts.map +1 -0
  24. package/dist/domain/featureCode.js +12 -0
  25. package/dist/domain/featureCode.js.map +1 -0
  26. package/dist/domain/journal.d.ts +7 -392
  27. package/dist/domain/journal.d.ts.map +1 -1
  28. package/dist/domain/journal.js +6 -118
  29. package/dist/domain/journal.js.map +1 -1
  30. package/dist/domain/ledger.d.ts +4 -328
  31. package/dist/domain/ledger.d.ts.map +1 -1
  32. package/dist/domain/ledger.js +11 -317
  33. package/dist/domain/ledger.js.map +1 -1
  34. package/dist/domain/messages.d.ts +202 -0
  35. package/dist/domain/messages.d.ts.map +1 -0
  36. package/dist/domain/messages.js +293 -0
  37. package/dist/domain/messages.js.map +1 -0
  38. package/dist/domain/outcome.d.ts +3 -0
  39. package/dist/domain/outcome.d.ts.map +1 -0
  40. package/dist/domain/outcome.js +2 -0
  41. package/dist/domain/outcome.js.map +1 -0
  42. package/dist/domain/posting.d.ts +5 -102
  43. package/dist/domain/posting.d.ts.map +1 -1
  44. package/dist/domain/posting.js +3 -55
  45. package/dist/domain/posting.js.map +1 -1
  46. package/dist/domain/qualityCheckFault.d.ts +1 -41
  47. package/dist/domain/qualityCheckFault.d.ts.map +1 -1
  48. package/dist/domain/qualityCheckFault.js +0 -24
  49. package/dist/domain/qualityCheckFault.js.map +1 -1
  50. package/dist/domain/qualityCheckReconciliation.d.ts +5 -278
  51. package/dist/domain/qualityCheckReconciliation.d.ts.map +1 -1
  52. package/dist/domain/qualityCheckReconciliation.js +53 -453
  53. package/dist/domain/qualityCheckReconciliation.js.map +1 -1
  54. package/dist/domain/qualityCheckReconciliationFault.d.ts +0 -19
  55. package/dist/domain/qualityCheckReconciliationFault.d.ts.map +1 -1
  56. package/dist/domain/qualityCheckReconciliationFault.js +1 -24
  57. package/dist/domain/qualityCheckReconciliationFault.js.map +1 -1
  58. package/dist/domain/scenarioCodeError.d.ts +16 -0
  59. package/dist/domain/scenarioCodeError.d.ts.map +1 -0
  60. package/dist/domain/scenarioCodeError.js +4 -0
  61. package/dist/domain/scenarioCodeError.js.map +1 -0
  62. package/dist/domain/scenarioReconciliation.d.ts +0 -205
  63. package/dist/domain/scenarioReconciliation.d.ts.map +1 -1
  64. package/dist/domain/scenarioReconciliation.js +1 -98
  65. package/dist/domain/scenarioReconciliation.js.map +1 -1
  66. package/dist/domain/scnAllocation.d.ts +27 -0
  67. package/dist/domain/scnAllocation.d.ts.map +1 -0
  68. package/dist/domain/scnAllocation.js +33 -0
  69. package/dist/domain/scnAllocation.js.map +1 -0
  70. package/dist/domain/verdictCode.d.ts +10 -0
  71. package/dist/domain/verdictCode.d.ts.map +1 -0
  72. package/dist/domain/verdictCode.js +16 -0
  73. package/dist/domain/verdictCode.js.map +1 -0
  74. package/dist/index.d.ts +13 -39
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +7 -87
  77. package/dist/index.js.map +1 -1
  78. package/dist/internal.d.ts +3 -27
  79. package/dist/internal.d.ts.map +1 -1
  80. package/dist/internal.js +3 -94
  81. package/dist/internal.js.map +1 -1
  82. package/dist/lib/bareTerm.d.ts +0 -39
  83. package/dist/lib/bareTerm.d.ts.map +1 -1
  84. package/dist/lib/bareTerm.js +0 -39
  85. package/dist/lib/bareTerm.js.map +1 -1
  86. package/dist/lib/portablePath.d.ts.map +1 -1
  87. package/dist/lib/portablePath.js +0 -14
  88. package/dist/lib/portablePath.js.map +1 -1
  89. package/dist/lib/scnCitation.d.ts +0 -32
  90. package/dist/lib/scnCitation.d.ts.map +1 -1
  91. package/dist/lib/scnCitation.js +2 -42
  92. package/dist/lib/scnCitation.js.map +1 -1
  93. package/dist/model.d.ts +0 -23
  94. package/dist/model.d.ts.map +1 -1
  95. package/dist/model.js +0 -23
  96. package/dist/model.js.map +1 -1
  97. package/dist/parse/checkScriptsRunInCI.d.ts +5 -168
  98. package/dist/parse/checkScriptsRunInCI.d.ts.map +1 -1
  99. package/dist/parse/checkScriptsRunInCI.js +11 -171
  100. package/dist/parse/checkScriptsRunInCI.js.map +1 -1
  101. package/dist/parse/ciStepRecord.d.ts +4 -118
  102. package/dist/parse/ciStepRecord.d.ts.map +1 -1
  103. package/dist/parse/ciStepRecord.js +18 -225
  104. package/dist/parse/ciStepRecord.js.map +1 -1
  105. package/dist/parse/commandRuns.d.ts +0 -39
  106. package/dist/parse/commandRuns.d.ts.map +1 -1
  107. package/dist/parse/commandRuns.js +6 -67
  108. package/dist/parse/commandRuns.js.map +1 -1
  109. package/dist/parse/cucumber.d.ts +0 -53
  110. package/dist/parse/cucumber.d.ts.map +1 -1
  111. package/dist/parse/cucumber.js +41 -145
  112. package/dist/parse/cucumber.js.map +1 -1
  113. package/dist/parse/discoveryScope.d.ts +1 -46
  114. package/dist/parse/discoveryScope.d.ts.map +1 -1
  115. package/dist/parse/discoveryScope.js +1 -56
  116. package/dist/parse/discoveryScope.js.map +1 -1
  117. package/dist/parse/fitnessCitations.d.ts +1 -72
  118. package/dist/parse/fitnessCitations.d.ts.map +1 -1
  119. package/dist/parse/fitnessCitations.js +3 -55
  120. package/dist/parse/fitnessCitations.js.map +1 -1
  121. package/dist/parse/reconcilerSteps.d.ts +0 -46
  122. package/dist/parse/reconcilerSteps.d.ts.map +1 -1
  123. package/dist/parse/reconcilerSteps.js +2 -64
  124. package/dist/parse/reconcilerSteps.js.map +1 -1
  125. package/dist/parse/runningStaticChecks.d.ts +2 -118
  126. package/dist/parse/runningStaticChecks.d.ts.map +1 -1
  127. package/dist/parse/runningStaticChecks.js +14 -273
  128. package/dist/parse/runningStaticChecks.js.map +1 -1
  129. package/dist/parse/scenarioCodeErrors.d.ts +12 -0
  130. package/dist/parse/scenarioCodeErrors.d.ts.map +1 -0
  131. package/dist/parse/scenarioCodeErrors.js +78 -0
  132. package/dist/parse/scenarioCodeErrors.js.map +1 -0
  133. package/dist/parse/scenarios.d.ts +3 -228
  134. package/dist/parse/scenarios.d.ts.map +1 -1
  135. package/dist/parse/scenarios.js +20 -457
  136. package/dist/parse/scenarios.js.map +1 -1
  137. package/dist/parse/stepAccounting.d.ts +0 -46
  138. package/dist/parse/stepAccounting.d.ts.map +1 -1
  139. package/dist/parse/stepAccounting.js +0 -54
  140. package/dist/parse/stepAccounting.js.map +1 -1
  141. package/dist/parse/stepExclusions.d.ts +0 -47
  142. package/dist/parse/stepExclusions.d.ts.map +1 -1
  143. package/dist/parse/stepExclusions.js +2 -50
  144. package/dist/parse/stepExclusions.js.map +1 -1
  145. package/dist/parse/stepNames.d.ts +0 -27
  146. package/dist/parse/stepNames.d.ts.map +1 -1
  147. package/dist/parse/stepNames.js +0 -27
  148. package/dist/parse/stepNames.js.map +1 -1
  149. package/dist/parse/targetCorpus.d.ts +1 -78
  150. package/dist/parse/targetCorpus.d.ts.map +1 -1
  151. package/dist/parse/targetCorpus.js +4 -46
  152. package/dist/parse/targetCorpus.js.map +1 -1
  153. package/dist/parse/targetManifest.d.ts +8 -146
  154. package/dist/parse/targetManifest.d.ts.map +1 -1
  155. package/dist/parse/targetManifest.js +47 -198
  156. package/dist/parse/targetManifest.js.map +1 -1
  157. package/dist/parse/vitest.d.ts +0 -60
  158. package/dist/parse/vitest.d.ts.map +1 -1
  159. package/dist/parse/vitest.js +2 -82
  160. package/dist/parse/vitest.js.map +1 -1
  161. package/dist/provenance/provenance.d.ts +2 -110
  162. package/dist/provenance/provenance.d.ts.map +1 -1
  163. package/dist/provenance/provenance.js +2 -58
  164. package/dist/provenance/provenance.js.map +1 -1
  165. package/dist/render/behaviouralRunners.d.ts +0 -29
  166. package/dist/render/behaviouralRunners.d.ts.map +1 -1
  167. package/dist/render/behaviouralRunners.js +6 -69
  168. package/dist/render/behaviouralRunners.js.map +1 -1
  169. package/dist/render/configurationNotRead.d.ts +3 -0
  170. package/dist/render/configurationNotRead.d.ts.map +1 -0
  171. package/dist/render/configurationNotRead.js +17 -0
  172. package/dist/render/configurationNotRead.js.map +1 -0
  173. package/dist/render/discoveryScope.d.ts +0 -37
  174. package/dist/render/discoveryScope.d.ts.map +1 -1
  175. package/dist/render/discoveryScope.js +3 -39
  176. package/dist/render/discoveryScope.js.map +1 -1
  177. package/dist/render/evidenceGrid.d.ts +1 -35
  178. package/dist/render/evidenceGrid.d.ts.map +1 -1
  179. package/dist/render/evidenceGrid.js +18 -100
  180. package/dist/render/evidenceGrid.js.map +1 -1
  181. package/dist/render/excludedSteps.d.ts +0 -26
  182. package/dist/render/excludedSteps.d.ts.map +1 -1
  183. package/dist/render/excludedSteps.js +4 -32
  184. package/dist/render/excludedSteps.js.map +1 -1
  185. package/dist/render/json.d.ts +0 -11
  186. package/dist/render/json.d.ts.map +1 -1
  187. package/dist/render/json.js +0 -11
  188. package/dist/render/json.js.map +1 -1
  189. package/dist/render/markdown.d.ts +0 -54
  190. package/dist/render/markdown.d.ts.map +1 -1
  191. package/dist/render/markdown.js +123 -463
  192. package/dist/render/markdown.js.map +1 -1
  193. package/dist/render/provenanceSection.d.ts +0 -22
  194. package/dist/render/provenanceSection.d.ts.map +1 -1
  195. package/dist/render/provenanceSection.js +10 -53
  196. package/dist/render/provenanceSection.js.map +1 -1
  197. package/dist/render/reconcilerSteps.d.ts +0 -25
  198. package/dist/render/reconcilerSteps.d.ts.map +1 -1
  199. package/dist/render/reconcilerSteps.js +5 -30
  200. package/dist/render/reconcilerSteps.js.map +1 -1
  201. package/dist/render/runVerdict.d.ts +0 -38
  202. package/dist/render/runVerdict.d.ts.map +1 -1
  203. package/dist/render/runVerdict.js +62 -129
  204. package/dist/render/runVerdict.js.map +1 -1
  205. package/dist/render/scenarioCodeErrorsSection.d.ts +3 -0
  206. package/dist/render/scenarioCodeErrorsSection.d.ts.map +1 -0
  207. package/dist/render/scenarioCodeErrorsSection.js +45 -0
  208. package/dist/render/scenarioCodeErrorsSection.js.map +1 -0
  209. package/dist/render/staticChecks.d.ts +0 -20
  210. package/dist/render/staticChecks.d.ts.map +1 -1
  211. package/dist/render/staticChecks.js +4 -61
  212. package/dist/render/staticChecks.js.map +1 -1
  213. package/dist/render/stepAccounting.d.ts +0 -36
  214. package/dist/render/stepAccounting.d.ts.map +1 -1
  215. package/dist/render/stepAccounting.js +5 -49
  216. package/dist/render/stepAccounting.js.map +1 -1
  217. package/dist/render/testVolume.d.ts +0 -25
  218. package/dist/render/testVolume.d.ts.map +1 -1
  219. package/dist/render/testVolume.js +4 -35
  220. package/dist/render/testVolume.js.map +1 -1
  221. package/package.json +4 -1
  222. package/dist/domain/checkCharacteristics.d.ts +0 -88
  223. package/dist/domain/checkCharacteristics.d.ts.map +0 -1
  224. package/dist/domain/checkCharacteristics.js +0 -109
  225. package/dist/domain/checkCharacteristics.js.map +0 -1
  226. package/dist/domain/fitnessChecks.d.ts +0 -79
  227. package/dist/domain/fitnessChecks.d.ts.map +0 -1
  228. package/dist/domain/fitnessChecks.js +0 -81
  229. package/dist/domain/fitnessChecks.js.map +0 -1
  230. package/dist/domain/qualityCheckFaultMessages.d.ts +0 -43
  231. package/dist/domain/qualityCheckFaultMessages.d.ts.map +0 -1
  232. package/dist/domain/qualityCheckFaultMessages.js +0 -38
  233. package/dist/domain/qualityCheckFaultMessages.js.map +0 -1
  234. package/dist/lib/featureCode.d.ts +0 -21
  235. package/dist/lib/featureCode.d.ts.map +0 -1
  236. package/dist/lib/featureCode.js +0 -24
  237. package/dist/lib/featureCode.js.map +0 -1
  238. package/dist/parse/corpusCodeFaults.d.ts +0 -76
  239. package/dist/parse/corpusCodeFaults.d.ts.map +0 -1
  240. package/dist/parse/corpusCodeFaults.js +0 -121
  241. package/dist/parse/corpusCodeFaults.js.map +0 -1
  242. package/dist/parse/corpusFaults.d.ts +0 -124
  243. package/dist/parse/corpusFaults.d.ts.map +0 -1
  244. package/dist/parse/corpusFaults.js +0 -72
  245. package/dist/parse/corpusFaults.js.map +0 -1
  246. package/dist/parse/corpusGrammarFaults.d.ts +0 -71
  247. package/dist/parse/corpusGrammarFaults.d.ts.map +0 -1
  248. package/dist/parse/corpusGrammarFaults.js +0 -292
  249. package/dist/parse/corpusGrammarFaults.js.map +0 -1
@@ -1,79 +0,0 @@
1
- /**
2
- * THE FITNESS CHECK ROWS — what a CONVERTED check says about itself, keyed by the `@SCN` it is
3
- * about.
4
- *
5
- * @SCN the row what the corpus then reads
6
- * SCN-FIT-001 { characteristic: complexity } a @fitness scenario owes `complexity`
7
- *
8
- * THE TAG NAMES THE AXIS AND THE ROW NAMES THE SUBJECT. A bare characteristic tag answered two
9
- * questions at once — how a claim is proved, and what it is about — and the tier tags answer only
10
- * the first. So a converted scenario carries `@fitness` alone, and the characteristic moves here,
11
- * where it stays a first-class word the roll-up still groups by.
12
- *
13
- * NOT A SECOND OBLIGATION SHAPE. What a `@fitness` scenario raises is the same
14
- * `{ qualityCheck: "lint", staticCheck: <characteristic> }` a registered bare tag raises today, so
15
- * the pair key, the reconciler's static arm and the report's roll-up are all untouched. What
16
- * changed is only where the word came from.
17
- *
18
- * NOT THE (RETIRED) CHECK REGISTRY, AND THE DIFFERENCE IS THE SEAM THIS RETIRES. That registry
19
- * answered "which check is this runnable script handle", because a handle does not know what it
20
- * is for; the `@SCN`
21
- * is then resolved through the corpus, a second hop. A converted check is never discovered as a
22
- * handle — it is a scenario that ran, carrying its own tag line — so the `@SCN` is the KEY here
23
- * rather than something a lookup has to recover.
24
- *
25
- * PURE AND INJECTED — the rows arrive as data, read from the TARGET's own manifest at the app edge
26
- * (`specController.fitnessChecks`), the stance the retired `thresholdsOf` took. A target that
27
- * configures nothing raises nothing, so the reading is inert on a corpus
28
- * nobody has converted.
29
- */
30
- /**
31
- * ONE CONFIGURED ROW as the obligation rule reads it.
32
- *
33
- * The `scn` a row states is not a member here: it is this index's KEY, so a row cannot name one
34
- * scenario and be filed under another. The command a row states is not a member either — it is the
35
- * COMMAND half of the row and nothing on the debit side reads it. Every row is credited by its own
36
- * step's outcome in the run's record, so the characteristic is the whole of what the ledger reads.
37
- */
38
- export interface FitnessCheck {
39
- /** The bare characteristic this check asserts (`complexity`). */
40
- readonly characteristic: string;
41
- }
42
- /** The rows as the rule reads them — bare `@SCN` → the row naming that scenario's check. */
43
- export type FitnessCheckIndex = ReadonlyMap<string, FitnessCheck>;
44
- /**
45
- * Build the index from the rows a manifest holds.
46
- *
47
- * A LIST, NOT A BLOCK KEYED BY `@SCN`, and the shape is the row's own argument: a row is what a
48
- * check says about ITSELF — its `@SCN`, its characteristic, its command — so no one of those three
49
- * is promoted above the others by being the key somebody has to write it under. The `@SCN` becomes
50
- * the key HERE, where a lookup needs one.
51
- *
52
- * A MALFORMED ROW IS DROPPED, NOT TRUSTED AND NOT THROWN ON — the defensive stance the whole
53
- * `specController.*` family takes. Config is data from outside, and a reader that throws on a typo
54
- * turns one bad character into a run that produces no verdict at all, which is loud nowhere; a
55
- * dropped row leaves its scenario naming no characteristic, which the corpus reports.
56
- */
57
- export declare function fitnessChecksOf(entries: unknown): FitnessCheckIndex;
58
- /**
59
- * ONE CONFIGURED ROW THE TARGET'S CORPUS CARRIES NO SCENARIO FOR (3F-3472) — a check the manifest
60
- * declares and nothing in the corpus specifies.
61
- *
62
- * THE MIRROR OF `unconfiguredFitnessScenarios`, AND THE HALF THE BOOKS COULD NOT SEE. That one
63
- * reads a `@fitness` scenario no row names; this reads a row no scenario names. The asymmetry
64
- * between what each EARNS is the two facts' own: a scenario naming no row names no characteristic,
65
- * so there is nothing to put on the books and the census says who — a row names one, so there IS a
66
- * debit, and `features/fitness-checks.feature` promises it as "an Evidence Obligation nothing
67
- * observed".
68
- *
69
- * IT CARRIES THE CHARACTERISTIC BECAUSE THE OBLIGATION IT RAISES NAMES ONE. The `@SCN` alone would
70
- * leave the reader of this reading to go back to the index for the other half, which is the second
71
- * read `readTargetCorpus` composes its readings together to foreclose.
72
- */
73
- export interface UnspecifiedFitnessRow {
74
- /** The `@SCN` the row states, which no scenario in the target's corpus carries. */
75
- readonly scnId: string;
76
- /** The bare characteristic the row asserts (`complexity`) — what its debit is owed at. */
77
- readonly characteristic: string;
78
- }
79
- //# sourceMappingURL=fitnessChecks.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fitnessChecks.d.ts","sourceRoot":"","sources":["../../src/domain/fitnessChecks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,4FAA4F;AAC5F,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AA2BlE;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,iBAAiB,CAQnE;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,qBAAqB;IACpC,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,0FAA0F;IAC1F,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC"}
@@ -1,81 +0,0 @@
1
- /**
2
- * THE FITNESS CHECK ROWS — what a CONVERTED check says about itself, keyed by the `@SCN` it is
3
- * about.
4
- *
5
- * @SCN the row what the corpus then reads
6
- * SCN-FIT-001 { characteristic: complexity } a @fitness scenario owes `complexity`
7
- *
8
- * THE TAG NAMES THE AXIS AND THE ROW NAMES THE SUBJECT. A bare characteristic tag answered two
9
- * questions at once — how a claim is proved, and what it is about — and the tier tags answer only
10
- * the first. So a converted scenario carries `@fitness` alone, and the characteristic moves here,
11
- * where it stays a first-class word the roll-up still groups by.
12
- *
13
- * NOT A SECOND OBLIGATION SHAPE. What a `@fitness` scenario raises is the same
14
- * `{ qualityCheck: "lint", staticCheck: <characteristic> }` a registered bare tag raises today, so
15
- * the pair key, the reconciler's static arm and the report's roll-up are all untouched. What
16
- * changed is only where the word came from.
17
- *
18
- * NOT THE (RETIRED) CHECK REGISTRY, AND THE DIFFERENCE IS THE SEAM THIS RETIRES. That registry
19
- * answered "which check is this runnable script handle", because a handle does not know what it
20
- * is for; the `@SCN`
21
- * is then resolved through the corpus, a second hop. A converted check is never discovered as a
22
- * handle — it is a scenario that ran, carrying its own tag line — so the `@SCN` is the KEY here
23
- * rather than something a lookup has to recover.
24
- *
25
- * PURE AND INJECTED — the rows arrive as data, read from the TARGET's own manifest at the app edge
26
- * (`specController.fitnessChecks`), the stance the retired `thresholdsOf` took. A target that
27
- * configures nothing raises nothing, so the reading is inert on a corpus
28
- * nobody has converted.
29
- */
30
- import { bareTerm } from "../lib/bareTerm.js";
31
- /**
32
- * One entry as a manifest spells it, read into the pair a lookup can use, or `null` where it names
33
- * nothing one can.
34
- *
35
- * BOTH TERMS ARE STORED BARE. A manifest written by hand will sooner or later spell an `@SCN` — and
36
- * a characteristic — the way a feature file does, and both lookups match bare; stripping once here
37
- * rather than at every call site is the stance the retired `thresholdsOf` took.
38
- *
39
- * A ROW NAMING NEITHER TERM IS DROPPED WHOLE, never half-read. The two terms make one claim
40
- * together — THIS scenario asserts THIS characteristic — so a row missing either says nothing a
41
- * lookup can act on, and there is no lenient reading that does not invent one of them.
42
- */
43
- function fitnessCheckOf(entry) {
44
- // THE TWO STRING READS ARE THE WHOLE GUARD, and a shape test ahead of them would add no teeth: a
45
- // string, a number, a list and a function all answer `undefined` here, so each is refused by the
46
- // read that matters rather than by a clause restating it. The optional chain is what covers the
47
- // two values a property read would throw on.
48
- const named = entry;
49
- if (typeof named?.scn !== "string" || typeof named.characteristic !== "string")
50
- return null;
51
- const scnId = bareTerm(named.scn);
52
- const characteristic = bareTerm(named.characteristic);
53
- if (scnId === "" || characteristic === "")
54
- return null;
55
- return [scnId, { characteristic }];
56
- }
57
- /**
58
- * Build the index from the rows a manifest holds.
59
- *
60
- * A LIST, NOT A BLOCK KEYED BY `@SCN`, and the shape is the row's own argument: a row is what a
61
- * check says about ITSELF — its `@SCN`, its characteristic, its command — so no one of those three
62
- * is promoted above the others by being the key somebody has to write it under. The `@SCN` becomes
63
- * the key HERE, where a lookup needs one.
64
- *
65
- * A MALFORMED ROW IS DROPPED, NOT TRUSTED AND NOT THROWN ON — the defensive stance the whole
66
- * `specController.*` family takes. Config is data from outside, and a reader that throws on a typo
67
- * turns one bad character into a run that produces no verdict at all, which is loud nowhere; a
68
- * dropped row leaves its scenario naming no characteristic, which the corpus reports.
69
- */
70
- export function fitnessChecksOf(entries) {
71
- if (!Array.isArray(entries))
72
- return new Map();
73
- const index = new Map();
74
- for (const entry of entries) {
75
- const row = fitnessCheckOf(entry);
76
- if (row !== null)
77
- index.set(row[0], row[1]);
78
- }
79
- return index;
80
- }
81
- //# sourceMappingURL=fitnessChecks.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fitnessChecks.js","sourceRoot":"","sources":["../../src/domain/fitnessChecks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAkB9C;;;;;;;;;;;GAWG;AACH,SAAS,cAAc,CAAC,KAAc;IACpC,iGAAiG;IACjG,iGAAiG;IACjG,gGAAgG;IAChG,6CAA6C;IAC7C,MAAM,KAAK,GAAG,KAAuE,CAAC;IACtF,IAAI,OAAO,KAAK,EAAE,GAAG,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,cAAc,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC5F,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,cAAc,GAAG,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACtD,IAAI,KAAK,KAAK,EAAE,IAAI,cAAc,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACvD,OAAO,CAAC,KAAK,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC9C,KAAK,MAAM,KAAK,IAAI,OAA6B,EAAE,CAAC;QAClD,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,GAAG,KAAK,IAAI;YAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -1,43 +0,0 @@
1
- /**
2
- * THE MESSAGE CATALOGUE (@SCN-MSG-001, 3F-2872) — the human-facing prose for every
3
- * `QualityCheckFaultCode`, and NOTHING ELSE.
4
- *
5
- * PURE DATA, DELIBERATELY. This module holds one table and no behaviour at all: the indexing
6
- * that turns a fault into its sentence lives in `qualityCheckFault.ts`, on the mutated surface,
7
- * where it belongs. The split is what makes the mutate exclusion honest — "do not mutate this
8
- * file" is defensible over a table of sentences and indefensible over anything that decides
9
- * something. A render helper parked here would leave the deciding logic unmutated too, and the
10
- * exclusion would then hide more than the prose it was granted for. NOTHING NOW ASSERTS THAT IT
11
- * DOES NOT: a check read the real stryker config back and redded on an exclusion that had widened,
12
- * until 3F-3490 retired it as a claim about our own configuration rather than about the product.
13
- * @SCN-MSG-002 keeps the half that IS about the product — every code renders a non-blank message
14
- * carrying its own fault's parameters, proved in `qualityCheckFaultMessages.test.ts` beside this
15
- * file — and the widened-exclusion residual is stated in `features/message-catalogue.feature`'s
16
- * preamble, where the next reader of the exclusion meets it.
17
- *
18
- * TOTALITY IS NOT ASSERTED, IT IS UNCONSTRUCTIBLE. `QualityCheckFaultMessages` is a mapped type
19
- * over the code union, so the compiler refuses both a code with no message AND a message reaching
20
- * for a parameter its own fault does not carry. That is the same type-forced totality
21
- * `OUTCOME_SIDE_PROFILE` and `OUTCOME_DESCRIPTION` already rely on: a new code cannot join the
22
- * union without stating its sentence here.
23
- */
24
- import { QualityCheckFaultCode, type QualityCheckFault } from "./qualityCheckFault.js";
25
- /**
26
- * One renderer per code, each seeing EXACTLY its own fault member.
27
- *
28
- * `Extract<…, { code: C }>` narrows per key, so a renderer for the obligation-side code cannot
29
- * reach a field only the observation-side fault carries — the compiler, not a reviewer, is what
30
- * keeps each sentence honest about the parameters available to it.
31
- */
32
- export type QualityCheckFaultMessages = {
33
- readonly [C in QualityCheckFaultCode]: (fault: Extract<QualityCheckFault, {
34
- code: C;
35
- }>) => string;
36
- };
37
- /**
38
- * The catalogue. Prose is the one thing in this tree that may be rewritten without a ticket, and
39
- * this is where it may be rewritten: no test reads these sentences, and no mutant is raised over
40
- * them once the exclusion lands.
41
- */
42
- export declare const QUALITY_CHECK_FAULT_MESSAGES: QualityCheckFaultMessages;
43
- //# sourceMappingURL=qualityCheckFaultMessages.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"qualityCheckFaultMessages.d.ts","sourceRoot":"","sources":["../../src/domain/qualityCheckFaultMessages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEvF;;;;;;GAMG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,EAAE,CAAC,IAAI,qBAAqB,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,iBAAiB,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,KAAK,MAAM;CAClG,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,EAAE,yBAS1C,CAAC"}
@@ -1,38 +0,0 @@
1
- /**
2
- * THE MESSAGE CATALOGUE (@SCN-MSG-001, 3F-2872) — the human-facing prose for every
3
- * `QualityCheckFaultCode`, and NOTHING ELSE.
4
- *
5
- * PURE DATA, DELIBERATELY. This module holds one table and no behaviour at all: the indexing
6
- * that turns a fault into its sentence lives in `qualityCheckFault.ts`, on the mutated surface,
7
- * where it belongs. The split is what makes the mutate exclusion honest — "do not mutate this
8
- * file" is defensible over a table of sentences and indefensible over anything that decides
9
- * something. A render helper parked here would leave the deciding logic unmutated too, and the
10
- * exclusion would then hide more than the prose it was granted for. NOTHING NOW ASSERTS THAT IT
11
- * DOES NOT: a check read the real stryker config back and redded on an exclusion that had widened,
12
- * until 3F-3490 retired it as a claim about our own configuration rather than about the product.
13
- * @SCN-MSG-002 keeps the half that IS about the product — every code renders a non-blank message
14
- * carrying its own fault's parameters, proved in `qualityCheckFaultMessages.test.ts` beside this
15
- * file — and the widened-exclusion residual is stated in `features/message-catalogue.feature`'s
16
- * preamble, where the next reader of the exclusion meets it.
17
- *
18
- * TOTALITY IS NOT ASSERTED, IT IS UNCONSTRUCTIBLE. `QualityCheckFaultMessages` is a mapped type
19
- * over the code union, so the compiler refuses both a code with no message AND a message reaching
20
- * for a parameter its own fault does not carry. That is the same type-forced totality
21
- * `OUTCOME_SIDE_PROFILE` and `OUTCOME_DESCRIPTION` already rely on: a new code cannot join the
22
- * union without stating its sentence here.
23
- */
24
- import { QualityCheckFaultCode } from "./qualityCheckFault.js";
25
- /**
26
- * The catalogue. Prose is the one thing in this tree that may be rewritten without a ticket, and
27
- * this is where it may be rewritten: no test reads these sentences, and no mutant is raised over
28
- * them once the exclusion lands.
29
- */
30
- export const QUALITY_CHECK_FAULT_MESSAGES = {
31
- [QualityCheckFaultCode.ObligationSideDivergesFromCanon]: (fault) => `QualityCheckReconciliation invariant (@SCN-LDG-030): outcome "${fault.outcome}" requires the ` +
32
- `evidence obligation (debit) side to be ${fault.required}, but it was ` +
33
- `${fault.actual}.`,
34
- [QualityCheckFaultCode.ObservationSideDivergesFromCanon]: (fault) => `QualityCheckReconciliation invariant (@SCN-LDG-030): outcome "${fault.outcome}" requires the ` +
35
- `evidence observation (credit) side to be ${fault.required}, but it was ` +
36
- `${fault.actual}.`,
37
- };
38
- //# sourceMappingURL=qualityCheckFaultMessages.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"qualityCheckFaultMessages.js","sourceRoot":"","sources":["../../src/domain/qualityCheckFaultMessages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,qBAAqB,EAA0B,MAAM,wBAAwB,CAAC;AAavF;;;;GAIG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAA8B;IACrE,CAAC,qBAAqB,CAAC,+BAA+B,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CACjE,iEAAiE,KAAK,CAAC,OAAO,iBAAiB;QAC/F,0CAA0C,KAAK,CAAC,QAAQ,eAAe;QACvE,GAAG,KAAK,CAAC,MAAM,GAAG;IACpB,CAAC,qBAAqB,CAAC,gCAAgC,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAClE,iEAAiE,KAAK,CAAC,OAAO,iBAAiB;QAC/F,4CAA4C,KAAK,CAAC,QAAQ,eAAe;QACzE,GAAG,KAAK,CAAC,MAAM,GAAG;CACrB,CAAC"}
@@ -1,21 +0,0 @@
1
- /**
2
- * The `scnId → feature-code` grammar helper — the pure core of the feature-code
3
- * registry (split out of the old spec/featureCodes.ts). Per Evidence
4
- * Manifesto §9A a scenario id is `SCN-<FFF>-<NNN>` where `<FFF>` is 2–5 uppercase
5
- * alphanumerics. This is the ONE engine-side owner of parsing the `<FFF>` off a bare
6
- * scenario id; the impure feature-file discovery (`discoverFeatures`) lives in
7
- * ingest/ingestScenarios.ts. The duplicate-code lint was product-side in
8
- * tests/checks/featureCodes.ts until 3F-3313 and is now @SCN-STG-010, a rule of the shipped
9
- * `spec-controller tags` command in parse/corpusFaults.ts.
10
- *
11
- * Reused by the by-feature report grouping (@SCN-RPT-006).
12
- */
13
- /**
14
- * Parse the feature code (the `<FFF>`) from a bare scenario id of the form
15
- * `SCN-<FFF>-<NNN>` (no leading `@`). Returns null when the id is malformed. The
16
- * single owner of `scnId → feature-code` parsing — callers reuse this rather than
17
- * re-deriving a regex (Evidence Manifesto §9A: a scenario id is `SCN-<FFF>-<NNN>`
18
- * where `<FFF>` is 2–5 uppercase alphanumerics).
19
- */
20
- export declare function featureCodeOf(scnId: string): string | null;
21
- //# sourceMappingURL=featureCode.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"featureCode.d.ts","sourceRoot":"","sources":["../../src/lib/featureCode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG1D"}
@@ -1,24 +0,0 @@
1
- /**
2
- * The `scnId → feature-code` grammar helper — the pure core of the feature-code
3
- * registry (split out of the old spec/featureCodes.ts). Per Evidence
4
- * Manifesto §9A a scenario id is `SCN-<FFF>-<NNN>` where `<FFF>` is 2–5 uppercase
5
- * alphanumerics. This is the ONE engine-side owner of parsing the `<FFF>` off a bare
6
- * scenario id; the impure feature-file discovery (`discoverFeatures`) lives in
7
- * ingest/ingestScenarios.ts. The duplicate-code lint was product-side in
8
- * tests/checks/featureCodes.ts until 3F-3313 and is now @SCN-STG-010, a rule of the shipped
9
- * `spec-controller tags` command in parse/corpusFaults.ts.
10
- *
11
- * Reused by the by-feature report grouping (@SCN-RPT-006).
12
- */
13
- /**
14
- * Parse the feature code (the `<FFF>`) from a bare scenario id of the form
15
- * `SCN-<FFF>-<NNN>` (no leading `@`). Returns null when the id is malformed. The
16
- * single owner of `scnId → feature-code` parsing — callers reuse this rather than
17
- * re-deriving a regex (Evidence Manifesto §9A: a scenario id is `SCN-<FFF>-<NNN>`
18
- * where `<FFF>` is 2–5 uppercase alphanumerics).
19
- */
20
- export function featureCodeOf(scnId) {
21
- const match = /^SCN-([A-Z0-9]{2,5})-\d+$/.exec(scnId);
22
- return match ? match[1] : null;
23
- }
24
- //# sourceMappingURL=featureCode.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"featureCode.js","sourceRoot":"","sources":["../../src/lib/featureCode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,KAAK,GAAG,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,CAAC"}
@@ -1,76 +0,0 @@
1
- /**
2
- * THE CODE RULES of `spec-controller tags` — everything about a feature CODE binding to a feature
3
- * FILE. Its sibling holds the other question: `corpusGrammarFaults.ts` whether a tag on a scenario
4
- * means anything. `corpusFaults.ts` composes the two and is the only entry point either of them
5
- * has.
6
- *
7
- * WHY THE MODULE IS SPLIT AT ALL, AND WHY ON THIS SEAM. The rules were authored in one module and
8
- * that module reached the 400-line `max-lines` ceiling with four more grammar clauses still to
9
- * land. The ceiling is not negotiable and an exception entry would have bought silence rather than
10
- * a smaller module (@SCN-FIT-001), so the split is the answer canon already named. The seam is the
11
- * one the rules themselves have: a code rule asks *does this code name exactly one file, and is
12
- * this scenario written in the file its own code names* — questions answered from the corpus's
13
- * SHAPE, needing nothing about the target. A grammar rule asks *does this word mean anything
14
- * here*, and answers it off the target's own manifest. Two questions, two inputs, two modules.
15
- *
16
- * THE PAIR BELOW IS ONE RULE READ FROM BOTH ENDS. `duplicateFeatureCodes` holds one code to one
17
- * file; `foreignScenarioCodes` holds a file's scenarios to the code that file carries. Together
18
- * they are what the hand-kept 33-entry allocation table was really enforcing — this code belongs
19
- * to this file — asked of the corpus about itself rather than of a second list a consumer has
20
- * never seen.
21
- */
22
- import type { CorpusFault, CorpusFile } from "./corpusFaults.js";
23
- /**
24
- * A feature code carried by more than one feature file (@SCN-STG-010).
25
- *
26
- * THE FAULT IS THE PAIR, NOT EITHER FILE, which is why one finding names them all rather than
27
- * one finding naming each. Neither file is the offender: what is wrong is that a code names two
28
- * of them, and a message naming one has already decided which of the two should change.
29
- *
30
- * WHAT GOES WRONG WITHOUT IT, MEASURED. Over a corpus whose `one.feature` and `two.feature` both
31
- * carry `@TGT`, `balance` runs clean through and prints ONE by-feature row — `two (TGT)` —
32
- * claiming a scenario that lives in `one`. Not a red and not a warning: a report cell that says
33
- * something false, in the section a reader goes to first.
34
- *
35
- * AN UNCODED FILE IS NOT A FAULT HERE, and that is a scope line rather than an omission. A file
36
- * carrying no header code while its scenarios carry `@SCN` ids is admitted unchanged; whether
37
- * that should red is a policy question about gradual adoption, filed as its own ticket (3F-3314).
38
- * `null` is therefore skipped rather than treated as a code two files could share.
39
- */
40
- export declare function duplicateFeatureCodes(features: readonly CorpusFile[]): CorpusFault[];
41
- /**
42
- * A scenario whose `@SCN` names a feature its own file is not (@SCN-STG-011).
43
- *
44
- * THE OTHER HALF OF THE PAIR ABOVE. That rule holds one code to one file; this one holds a
45
- * file's scenarios to the code that file carries.
46
- *
47
- * WHAT GOES WRONG WITHOUT IT, MEASURED. Over a corpus whose `@TGT`-headed file holds
48
- * `@SCN-ZZZ-001`, `balance` runs clean through and prints a by-feature row for a feature `ZZZ`
49
- * it INVENTED from the id alone — no file in the corpus carries that code — and the
50
- * feature-code lint over the same tree reports every code a header names unique and registered.
51
- * Silent in both readers, which is exactly the pair of places a reader looks.
52
- *
53
- * THE FINDING NAMES THREE THINGS AND ONE SCENARIO. The file and the id say where to go; the
54
- * code the file CARRIES is the half of the disagreement the author cannot read off the id, and
55
- * it is what decides which of the two remedies they want — re-code the scenario, or move it.
56
- * And it is raised per offending scenario, never per file: a file may hold many scenarios of
57
- * which one is wrong, and a finding naming the file alone convicts the rest of them.
58
- *
59
- * AN UNCODED FILE RAISES NOTHING, deliberately rather than by omission. A file carrying no
60
- * header code has nothing for an id to be foreign TO. Whether that should red is a policy
61
- * question about gradual adoption, filed as its own ticket (3F-3314) — and it is the same
62
- * `null`-is-not-a-code line the duplicate rule draws, drawn once more here so the two cannot
63
- * come to disagree about what an uncoded file is.
64
- *
65
- * AND A MALFORMED ID RAISES NOTHING EITHER, because something else already does. `featureCodeOf`
66
- * is the ONE owner of the `SCN-<FFF>-<NNN>` grammar in this engine, and an id it cannot parse
67
- * has no feature part to compare — that fault is `no-scn-code`, which a reconciliation raises
68
- * and names by id. A second diagnostic here would print one fault's remedy at the other's author.
69
- *
70
- * The tag walk is `parseTaggedScenarios`, which inherits Feature- and Rule-level tags exactly as
71
- * cucumber does. A hand-rolled scan of the tag lines is the second reading that walk was
72
- * extracted to end, and it is what a rule ABOUT ids can least afford: an id hoisted to a `Rule:`
73
- * belongs to every scenario beneath it, and a scan that missed that would pass over the file.
74
- */
75
- export declare function foreignScenarioCodes(features: readonly CorpusFile[]): CorpusFault[];
76
- //# sourceMappingURL=corpusCodeFaults.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"corpusCodeFaults.d.ts","sourceRoot":"","sources":["../../src/parse/corpusCodeFaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGjE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,GAAG,WAAW,EAAE,CAuBpF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,GAAG,WAAW,EAAE,CAoBnF"}
@@ -1,121 +0,0 @@
1
- /**
2
- * THE CODE RULES of `spec-controller tags` — everything about a feature CODE binding to a feature
3
- * FILE. Its sibling holds the other question: `corpusGrammarFaults.ts` whether a tag on a scenario
4
- * means anything. `corpusFaults.ts` composes the two and is the only entry point either of them
5
- * has.
6
- *
7
- * WHY THE MODULE IS SPLIT AT ALL, AND WHY ON THIS SEAM. The rules were authored in one module and
8
- * that module reached the 400-line `max-lines` ceiling with four more grammar clauses still to
9
- * land. The ceiling is not negotiable and an exception entry would have bought silence rather than
10
- * a smaller module (@SCN-FIT-001), so the split is the answer canon already named. The seam is the
11
- * one the rules themselves have: a code rule asks *does this code name exactly one file, and is
12
- * this scenario written in the file its own code names* — questions answered from the corpus's
13
- * SHAPE, needing nothing about the target. A grammar rule asks *does this word mean anything
14
- * here*, and answers it off the target's own manifest. Two questions, two inputs, two modules.
15
- *
16
- * THE PAIR BELOW IS ONE RULE READ FROM BOTH ENDS. `duplicateFeatureCodes` holds one code to one
17
- * file; `foreignScenarioCodes` holds a file's scenarios to the code that file carries. Together
18
- * they are what the hand-kept 33-entry allocation table was really enforcing — this code belongs
19
- * to this file — asked of the corpus about itself rather than of a second list a consumer has
20
- * never seen.
21
- */
22
- import { featureCodeOf } from "../lib/featureCode.js";
23
- import { parseTaggedScenarios } from "./scenarios.js";
24
- /**
25
- * A feature code carried by more than one feature file (@SCN-STG-010).
26
- *
27
- * THE FAULT IS THE PAIR, NOT EITHER FILE, which is why one finding names them all rather than
28
- * one finding naming each. Neither file is the offender: what is wrong is that a code names two
29
- * of them, and a message naming one has already decided which of the two should change.
30
- *
31
- * WHAT GOES WRONG WITHOUT IT, MEASURED. Over a corpus whose `one.feature` and `two.feature` both
32
- * carry `@TGT`, `balance` runs clean through and prints ONE by-feature row — `two (TGT)` —
33
- * claiming a scenario that lives in `one`. Not a red and not a warning: a report cell that says
34
- * something false, in the section a reader goes to first.
35
- *
36
- * AN UNCODED FILE IS NOT A FAULT HERE, and that is a scope line rather than an omission. A file
37
- * carrying no header code while its scenarios carry `@SCN` ids is admitted unchanged; whether
38
- * that should red is a policy question about gradual adoption, filed as its own ticket (3F-3314).
39
- * `null` is therefore skipped rather than treated as a code two files could share.
40
- */
41
- export function duplicateFeatureCodes(features) {
42
- const filesByCode = new Map();
43
- for (const file of features) {
44
- if (file.featureCode === null)
45
- continue;
46
- filesByCode.set(file.featureCode, [
47
- ...(filesByCode.get(file.featureCode) ?? []),
48
- `${file.slug}.feature`,
49
- ]);
50
- }
51
- const faults = [];
52
- for (const [code, files] of filesByCode) {
53
- if (files.length < 2)
54
- continue;
55
- faults.push({
56
- kind: "duplicate-feature-code",
57
- message: `duplicate-feature-code: the feature code @${code} is carried by ${files.length} feature ` +
58
- `files — ${files.join(", ")}. A feature code names exactly one feature file: a ` +
59
- `reconciliation's by-feature cut groups on it, so two files sharing a code report as one ` +
60
- `row and attribute one file's scenarios to the other. Give one of them a code of its own.`,
61
- });
62
- }
63
- return faults;
64
- }
65
- /**
66
- * A scenario whose `@SCN` names a feature its own file is not (@SCN-STG-011).
67
- *
68
- * THE OTHER HALF OF THE PAIR ABOVE. That rule holds one code to one file; this one holds a
69
- * file's scenarios to the code that file carries.
70
- *
71
- * WHAT GOES WRONG WITHOUT IT, MEASURED. Over a corpus whose `@TGT`-headed file holds
72
- * `@SCN-ZZZ-001`, `balance` runs clean through and prints a by-feature row for a feature `ZZZ`
73
- * it INVENTED from the id alone — no file in the corpus carries that code — and the
74
- * feature-code lint over the same tree reports every code a header names unique and registered.
75
- * Silent in both readers, which is exactly the pair of places a reader looks.
76
- *
77
- * THE FINDING NAMES THREE THINGS AND ONE SCENARIO. The file and the id say where to go; the
78
- * code the file CARRIES is the half of the disagreement the author cannot read off the id, and
79
- * it is what decides which of the two remedies they want — re-code the scenario, or move it.
80
- * And it is raised per offending scenario, never per file: a file may hold many scenarios of
81
- * which one is wrong, and a finding naming the file alone convicts the rest of them.
82
- *
83
- * AN UNCODED FILE RAISES NOTHING, deliberately rather than by omission. A file carrying no
84
- * header code has nothing for an id to be foreign TO. Whether that should red is a policy
85
- * question about gradual adoption, filed as its own ticket (3F-3314) — and it is the same
86
- * `null`-is-not-a-code line the duplicate rule draws, drawn once more here so the two cannot
87
- * come to disagree about what an uncoded file is.
88
- *
89
- * AND A MALFORMED ID RAISES NOTHING EITHER, because something else already does. `featureCodeOf`
90
- * is the ONE owner of the `SCN-<FFF>-<NNN>` grammar in this engine, and an id it cannot parse
91
- * has no feature part to compare — that fault is `no-scn-code`, which a reconciliation raises
92
- * and names by id. A second diagnostic here would print one fault's remedy at the other's author.
93
- *
94
- * The tag walk is `parseTaggedScenarios`, which inherits Feature- and Rule-level tags exactly as
95
- * cucumber does. A hand-rolled scan of the tag lines is the second reading that walk was
96
- * extracted to end, and it is what a rule ABOUT ids can least afford: an id hoisted to a `Rule:`
97
- * belongs to every scenario beneath it, and a scan that missed that would pass over the file.
98
- */
99
- export function foreignScenarioCodes(features) {
100
- const faults = [];
101
- for (const file of features) {
102
- if (file.featureCode === null)
103
- continue;
104
- for (const scenario of parseTaggedScenarios(file.source)) {
105
- const named = featureCodeOf(scenario.scnId);
106
- if (named === null || named === file.featureCode)
107
- continue;
108
- faults.push({
109
- kind: "foreign-scenario-code",
110
- message: `foreign-scenario-code: ${file.slug}.feature carries the feature code ` +
111
- `@${file.featureCode}, but holds the scenario @${scenario.scnId}, whose feature part ` +
112
- `names ${named}. A scenario's code names the file it is written in: a ` +
113
- `reconciliation's by-feature cut groups on the id, so this one opens a row for a ` +
114
- `feature no file in the corpus carries and files the scenario under it. Re-code the ` +
115
- `scenario for @${file.featureCode}, or move it to the file headed @${named}.`,
116
- });
117
- }
118
- }
119
- return faults;
120
- }
121
- //# sourceMappingURL=corpusCodeFaults.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"corpusCodeFaults.js","sourceRoot":"","sources":["../../src/parse/corpusCodeFaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAA+B;IACnE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAoB,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI;YAAE,SAAS;QACxC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE;YAChC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YAC5C,GAAG,IAAI,CAAC,IAAI,UAAU;SACvB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC;QACxC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC/B,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,wBAAwB;YAC9B,OAAO,EACL,6CAA6C,IAAI,kBAAkB,KAAK,CAAC,MAAM,WAAW;gBAC1F,WAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,qDAAqD;gBAChF,0FAA0F;gBAC1F,0FAA0F;SAC7F,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAA+B;IAClE,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI;YAAE,SAAS;QACxC,KAAK,MAAM,QAAQ,IAAI,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACzD,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC5C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC,WAAW;gBAAE,SAAS;YAC3D,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,uBAAuB;gBAC7B,OAAO,EACL,0BAA0B,IAAI,CAAC,IAAI,oCAAoC;oBACvE,IAAI,IAAI,CAAC,WAAW,6BAA6B,QAAQ,CAAC,KAAK,uBAAuB;oBACtF,SAAS,KAAK,yDAAyD;oBACvE,kFAAkF;oBAClF,qFAAqF;oBACrF,iBAAiB,IAAI,CAAC,WAAW,oCAAoC,KAAK,GAAG;aAChF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}