@3f-consulting/spec-controller-core 0.1.0-alpha.7 → 0.1.0-alpha.70

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 (257) 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 +30 -325
  5. package/dist/assemble/evidenceReconciliationFromSources.js.map +1 -1
  6. package/dist/assemble/renderInput.d.ts +7 -73
  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 +11 -46
  11. package/dist/census/evidenceObligations.d.ts.map +1 -1
  12. package/dist/census/evidenceObligations.js +19 -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 +21 -391
  19. package/dist/domain/evidenceReconciliation.d.ts.map +1 -1
  20. package/dist/domain/evidenceReconciliation.js +87 -382
  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 +8 -393
  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 +8 -328
  31. package/dist/domain/ledger.d.ts.map +1 -1
  32. package/dist/domain/ledger.js +23 -326
  33. package/dist/domain/ledger.js.map +1 -1
  34. package/dist/domain/messages.d.ts +213 -0
  35. package/dist/domain/messages.d.ts.map +1 -0
  36. package/dist/domain/messages.js +313 -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 +8 -105
  43. package/dist/domain/posting.d.ts.map +1 -1
  44. package/dist/domain/posting.js +4 -56
  45. package/dist/domain/posting.js.map +1 -1
  46. package/dist/domain/qualityCheckFault.d.ts +3 -43
  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 +7 -280
  51. package/dist/domain/qualityCheckReconciliation.d.ts.map +1 -1
  52. package/dist/domain/qualityCheckReconciliation.js +63 -463
  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 +2 -207
  63. package/dist/domain/scenarioReconciliation.d.ts.map +1 -1
  64. package/dist/domain/scenarioReconciliation.js +4 -101
  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 +14 -40
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +8 -88
  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 +2 -16
  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 +42 -146
  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 +2 -57
  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/runningFitnessFunctions.d.ts +9 -0
  126. package/dist/parse/runningFitnessFunctions.d.ts.map +1 -0
  127. package/dist/parse/runningFitnessFunctions.js +57 -0
  128. package/dist/parse/runningFitnessFunctions.js.map +1 -0
  129. package/dist/parse/scenarioCodeErrors.d.ts +11 -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 +1 -55
  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 +48 -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 +4 -83
  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 +21 -103
  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/fitnessFunctions.d.ts +3 -0
  186. package/dist/render/fitnessFunctions.d.ts.map +1 -0
  187. package/dist/render/fitnessFunctions.js +12 -0
  188. package/dist/render/fitnessFunctions.js.map +1 -0
  189. package/dist/render/json.d.ts +0 -11
  190. package/dist/render/json.d.ts.map +1 -1
  191. package/dist/render/json.js +0 -11
  192. package/dist/render/json.js.map +1 -1
  193. package/dist/render/markdown.d.ts +1 -55
  194. package/dist/render/markdown.d.ts.map +1 -1
  195. package/dist/render/markdown.js +128 -467
  196. package/dist/render/markdown.js.map +1 -1
  197. package/dist/render/provenanceSection.d.ts +0 -22
  198. package/dist/render/provenanceSection.d.ts.map +1 -1
  199. package/dist/render/provenanceSection.js +10 -53
  200. package/dist/render/provenanceSection.js.map +1 -1
  201. package/dist/render/reconcilerSteps.d.ts +0 -25
  202. package/dist/render/reconcilerSteps.d.ts.map +1 -1
  203. package/dist/render/reconcilerSteps.js +5 -30
  204. package/dist/render/reconcilerSteps.js.map +1 -1
  205. package/dist/render/runVerdict.d.ts +0 -38
  206. package/dist/render/runVerdict.d.ts.map +1 -1
  207. package/dist/render/runVerdict.js +62 -129
  208. package/dist/render/runVerdict.js.map +1 -1
  209. package/dist/render/scenarioCodeErrorsSection.d.ts +3 -0
  210. package/dist/render/scenarioCodeErrorsSection.d.ts.map +1 -0
  211. package/dist/render/scenarioCodeErrorsSection.js +45 -0
  212. package/dist/render/scenarioCodeErrorsSection.js.map +1 -0
  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
  250. package/dist/parse/runningStaticChecks.d.ts +0 -125
  251. package/dist/parse/runningStaticChecks.d.ts.map +0 -1
  252. package/dist/parse/runningStaticChecks.js +0 -316
  253. package/dist/parse/runningStaticChecks.js.map +0 -1
  254. package/dist/render/staticChecks.d.ts +0 -23
  255. package/dist/render/staticChecks.d.ts.map +0 -1
  256. package/dist/render/staticChecks.js +0 -69
  257. package/dist/render/staticChecks.js.map +0 -1
@@ -1,360 +1,65 @@
1
- /**
2
- * The SCENARIO reader — parse spec-controller's own `features/**\/*.feature` source
3
- * into evidence obligations: per scenario, `{ scnId, evidenceObligations }`, with
4
- * each (kind, level) drawn from the scenario's evidence tags (@unit → runtime/unit,
5
- * @integration → runtime/integration, @e2e → runtime/e2e, @performance →
6
- * runtime/performance — the evidence-obligation reading).
7
- *
8
- * One of the three separated inputs to the reconciler (obligations / observations /
9
- * static checks) — the embryonic obligation-side adapter, deliberately not a registry (v1).
10
- *
11
- * Approach: scan TAG LINES (a line whose first non-blank char is `@` and whose
12
- * every whitespace-separated token is a tag) for an @SCN-<FFF>-<NNN> id and any
13
- * co-located evidence-level tags. A scenario's @SCN id and its level tags sit on
14
- * the same accumulated tag block immediately above the Scenario keyword, so a tag
15
- * line carrying an @SCN id contributes that scenario's evidenceObligations from the level
16
- * tags found across the contiguous tag block.
17
- *
18
- * The `lint` quality-check is raised by a scenario's REGISTERED bare check tag, STEPS OR NONE
19
- * (`fitnessObligationsOf`, @SCN-LNT-006): the tag says which axis a scenario is on and the steps say
20
- * nothing about it (3F-3115). The retired `@lint=<guard>` form — where the scenario
21
- * named a runnable npm script and the run was matched back to it BY NAME — raises nothing
22
- * (@SCN-LNT-007): it supplies no citation, so anything it raised could never be credited under
23
- * the one posting rule and would read `missing` for ever. The form is inert in the READER, which
24
- * is what makes it retired rather than merely unused.
25
- *
26
- * Parent: @SCN-LDG-001.
27
- */
28
1
  import { AstBuilder, GherkinClassicTokenMatcher, Parser } from "@cucumber/gherkin";
29
2
  import { IdGenerator } from "@cucumber/messages";
30
3
  import { bareTerm } from "../lib/bareTerm.js";
31
- const SCN_CODE = /^SCN-[A-Z0-9]+-\d+$/;
32
- /**
33
- * The recognised `<quality-check>pending` lexicon (evidence-manifesto §11B) — a bare tag
34
- * (the `@` stripped) that DEFERS an obligation to a later slice. Exact-match keyed, so the
35
- * `pending` suffix is significant: `integrationpending` is NOT `integration`, and an
36
- * unrecognised `<x>pending` (or bare `pending`) is absent from the map → ignored. Unlike
37
- * `TAG_TO_QUALITY_CHECK`, this covers ALL FIVE quality-checks including `lint` (a pending
38
- * lint obligation is one-sided — no `staticCheck` payload).
39
- */
4
+ import { SCN_ID_SOURCE } from "../domain/featureCode.js";
5
+ import { CORE_MESSAGES, CoreMessage } from "../domain/messages.js";
6
+ export const SCN_CODE = new RegExp(`^${SCN_ID_SOURCE}$`);
40
7
  const PENDING_TAG_TO_QUALITY_CHECK = {
41
- lintpending: "lint",
8
+ fitnesspending: "fitness",
42
9
  unitpending: "unit",
43
10
  integrationpending: "integration",
44
11
  e2epending: "e2e",
45
12
  performancepending: "performance",
46
13
  };
47
- /**
48
- * Recognise a `<quality-check>pending` tag (evidence-manifesto §11B) — return its deferred
49
- * quality-check, or `null` when the bare tag is not one of the five recognised `<qc>pending`
50
- * (a bare tier tag, an unknown `<x>pending`, or bare `pending`). The pure per-tag helper
51
- * `parseScenarios` uses to derive a pending obligation.
52
- */
53
14
  export function pendingQualityCheck(tag) {
54
15
  return PENDING_TAG_TO_QUALITY_CHECK[tag] ?? null;
55
16
  }
56
- /**
57
- * Every recognised `<quality-check>pending` spelling, derived from the map above rather than
58
- * listed again (@SCN-STG-002, 3F-3302).
59
- *
60
- * WHY A LIST AND NOT JUST THE PREDICATE. `pendingQualityCheck` answers "is THIS tag one", which
61
- * is all an obligation needs. The tag-grammar rule needs the other direction too — the words to
62
- * measure an unrecognised tag AGAINST, so it can name the tier a typo resembles — and a list
63
- * written out over there would agree with this map by diligence and then drift the first time a
64
- * quality-check is added.
65
- */
66
- export const PENDING_QUALITY_CHECK_TAGS = Object.keys(PENDING_TAG_TO_QUALITY_CHECK);
67
17
  const TAG_TO_QUALITY_CHECK = {
68
18
  unit: "unit",
69
19
  integration: "integration",
70
20
  e2e: "e2e",
71
21
  performance: "performance",
72
22
  };
73
- /**
74
- * The bare tags that name a RUNTIME evidence tier, derived from the map above (@SCN-STG-002,
75
- * 3F-3302). Exported for the same reason as the pending list beside it, and kept beneath the map
76
- * it reads so the two can never be edited apart.
77
- */
78
- export const RUNTIME_QUALITY_CHECK_TAGS = Object.keys(TAG_TO_QUALITY_CHECK);
79
- /** Is a trimmed line a genuine Gherkin TAG LINE? Return its bare tags, else null. */
80
23
  function tagLineTags(line) {
81
- if (!line.startsWith("@"))
82
- return null;
83
24
  const tokens = line.split(/\s+/);
84
25
  if (!tokens.every((t) => t.startsWith("@")))
85
26
  return null;
86
27
  return tokens.map((t) => t.slice(1));
87
28
  }
88
- /**
89
- * `@SCN-FFF-NNN` — a raw scenario-id occurrence ANYWHERE in the source (tag line OR
90
- * the non-tag context — prose, comments, step text — the tag-line parser ignores).
91
- * The global flag counts every occurrence (@SCN-RPT-008).
92
- */
93
- const SCN_OCCURRENCE = /@SCN-[A-Z0-9]+-\d+/g;
94
- /**
95
- * Count every raw `@SCN-FFF-NNN` occurrence across the WHOLE source — including the
96
- * non-tag-line context (prose, comments, step text) the tag-line `parseScenarios`
97
- * deliberately ignores. A sibling read over the same source; `parseScenarios` is
98
- * unchanged. Each scenario contributes exactly one tag-line occurrence, so
99
- * the delta against `parseScenarios(...).length` is precisely the ids seen in non-tag
100
- * context.
101
- */
29
+ const SCN_OCCURRENCE = new RegExp(`@${SCN_ID_SOURCE}`, "g");
102
30
  export function countScnOccurrences(source) {
103
31
  return (source.match(SCN_OCCURRENCE) ?? []).length;
104
32
  }
105
- /**
106
- * The PROSE-ONLY @SCN codes (@SCN-RPT-015) — codes that appear in non-tag
107
- * context (prose / comments / step text) but are NEVER an @SCN tag ANYWHERE in the
108
- * corpus: dangling references. A CROSS-CORPUS set difference `proseCodes − tagCodes`
109
- * over ALL sources (unique, sorted): per source each line is inspected — a tag line
110
- * contributes its @SCN tokens to the TAG set; any other line contributes its @SCN
111
- * matches (the leading `@` stripped) to the PROSE set. The union across files is
112
- * load-bearing: a code tagged in one file but mentioned in prose in another is NOT
113
- * prose-only. Distinct from `countScnOccurrences`'s raw count (occurrences, not unique
114
- * dangling codes). The bare code (e.g. `SCN-FOO-001`) is its own locator.
115
- */
116
- export function proseOnlyCodes(sources) {
117
- const tag = new Set();
118
- const prose = new Set();
119
- for (const source of sources) {
120
- for (const rawLine of source.split(/\r?\n/)) {
121
- const line = rawLine.trim();
122
- const tags = line === "" ? null : tagLineTags(line);
123
- if (tags) {
124
- for (const t of tags)
125
- if (SCN_CODE.test(t))
126
- tag.add(t);
127
- }
128
- else {
129
- for (const m of line.matchAll(SCN_OCCURRENCE))
130
- prose.add(m[0].slice(1));
131
- }
132
- }
133
- }
134
- return [...prose].filter((code) => !tag.has(code)).sort();
135
- }
136
- /**
137
- * A Gherkin scenario-header line: `Scenario:` / `Scenario Outline:` / `Scenario
138
- * Template:` / `Example:` (the synonym for Scenario), capturing the name after the
139
- * colon. The colon is anchored immediately after the keyword, so `Examples:` (plural —
140
- * the Scenario Outline DATA TABLE, not a scenario) does NOT match. Longer keywords lead
141
- * the alternation for clarity.
142
- */
143
33
  const SCENARIO_HEADER = /^(?:Scenario Outline|Scenario Template|Scenario|Example):\s*(.*)$/;
144
- /**
145
- * Parse the UNTAGGED scenarios — Gherkin scenario headers whose preceding contiguous
146
- * tag block carries no `@SCN` id (@SCN-RPT-014). Mirrors `parseScenarios`'s
147
- * tag-block accumulation: a tag line accumulates the block; any non-tag line closes it.
148
- * At each scenario header, the just-accumulated block is checked for an `@SCN` — if it
149
- * has none, the scenario is untagged (returns its name). The obligation-side counterpart
150
- * to the evidenceObservations aggregate's anomaly terms: a scenario with no evidence anchor.
151
- */
152
34
  export function parseUntaggedScenarios(source) {
153
35
  const untagged = [];
154
36
  let blockTags = [];
155
37
  for (const rawLine of source.split(/\r?\n/)) {
156
38
  const line = rawLine.trim();
157
- const tags = line === "" ? null : tagLineTags(line);
39
+ const tags = tagLineTags(line);
158
40
  if (tags) {
159
41
  blockTags.push(...tags);
160
42
  continue;
161
43
  }
162
44
  const header = SCENARIO_HEADER.exec(line);
163
45
  if (header && !blockTags.some((t) => SCN_CODE.test(t))) {
164
- untagged.push(header[1].trim());
46
+ untagged.push(header[1]);
165
47
  }
166
- // Any non-tag line (a scenario header, a step, a blank, Feature:/Rule:) closes the block.
167
48
  blockTags = [];
168
49
  }
169
50
  return untagged;
170
51
  }
171
- /**
172
- * THE FITNESS OBLIGATIONS a scenario's tags raise (@SCN-LNT-006) — one per REGISTERED bare check
173
- * tag it carries, whether or not the scenario carries steps.
174
- *
175
- * THE TECHNIQUE LEAVES THE TAG. Under name-match the DEBIT cited: a scenario carried
176
- * `@lint=<handle>` and a run was matched back to it by name, so an obligation could only be raised
177
- * by naming a runnable script — which put one technique in front of a whole class of fitness
178
- * functions, and is why `complexity`, `typecheck` and `vocab` all had to spell themselves
179
- * `lint:something` to be seen at all. A bare tag drops it: `@complexity` is a flat peer of `@unit`
180
- * exactly as `@unit` is a flat peer of `@integration`. There is no `@behavioural=unit`, so there is
181
- * no `@fitness=complexity` (canon 2026-08-07, the bare-tags Correction).
182
- *
183
- * THE TAG IS THE DISCRIMINATOR, AND THE STEPS ARE NOT (3F-3115). A scenario carrying a registered
184
- * bare check owes that check from the row that carries it; a scenario carrying a tier tag owes its
185
- * tier. Steps say how a scenario is WRITTEN, not which axis it is ON, so a fitness scenario handed
186
- * a runnable example keeps the characteristic it was written to hold instead of swapping axes.
187
- *
188
- * THE `stepless` CONDITION THAT USED TO STAND HERE WAS A PROXY, AND IT READ THE WRONG SIGNAL —
189
- * having nothing to exemplify is why a fitness scenario usually carries no steps, a correlate of
190
- * being non-behavioural rather than the thing itself. The CREDIT side never read it: the citation
191
- * seam has always reached a stepped row, so the debit alone stopped short and such a row produced a
192
- * credit with no obligation to post to (3F-3092). Removing the condition removes that asymmetry;
193
- * no compensating rule is added on the credit side, and none is needed.
194
- *
195
- * AND THE FIELD THAT OUTLIVED THE CONDITION IS GONE WITH IT (3F-3369). `TaggedScenario` carried a
196
- * `stepless` boolean on after the rule stopped reading it, kept by a reason that was wrong twice
197
- * (3F-3134): it named `parse/scnTags.ts` as the surviving reader, which is not a path in this
198
- * repository, and the corpus check it meant computed its own steplessness off its own line parser
199
- * and never read this one. Both rules that reason named read the tag instead (@SCN-STG-005, and
200
- * the one-check rule until it left with the measured axis; 3F-3126, 3F-3516). So nothing asked
201
- * the walk for a scenario's SHAPE, and the walk stopped answering: steplessness is derived
202
- * nowhere in this tree, and a scenario's axis is its tag.
203
- *
204
- * SUPPLIED, NOT INFERRED. `checkTags` is the caller's set of recognised check tags, taken as
205
- * data. Without it every unrecognised tag would be a candidate check and `@smoke` would owe one;
206
- * with a prefix heuristic instead, `typecheck` would be missed, which is the reading 3F-2495 already
207
- * disproved on the discovery side. An empty set raises nothing, so this is inert on a corpus
208
- * that has not been swept.
209
- *
210
- * `seen` CARRIES THE CHECKS ALREADY RAISED, and is mutated here: a scenario's effective tags are
211
- * its own plus its `Rule:`'s and its `Feature:`'s (@SCN-LDG-020), so one check can reach one
212
- * scenario twice and is owed once. Two obligations for one check would leave the second `missing`
213
- * for ever — one run is one credit and can cite one `@SCN`.
214
- */
215
- function fitnessObligationsOf(tags, checkTags, seen) {
216
- const registered = new Set(checkTags);
217
- const raised = [];
218
- for (const tag of tags) {
219
- if (!registered.has(tag) || seen.has(tag))
220
- continue;
221
- seen.add(tag);
222
- raised.push({ qualityCheck: "lint", staticCheck: tag });
223
- }
224
- return raised;
225
- }
226
- /**
227
- * The one word a CONVERTED check's scenario carries — the axis, and nothing about the subject.
228
- *
229
- * It is a literal rather than a registered tag because it names no characteristic: `checkTags` is
230
- * the answer to "which words are checks here", and this word is the answer to "which axis is this
231
- * scenario on", which is the same question `unit` and `integration` answer for the other axis. A
232
- * target does not get to spell it differently for the reason nobody spells `@unit` differently.
233
- */
234
52
  export const FITNESS_AXIS_TAG = "fitness";
235
- /**
236
- * The obligation a CONVERTED check's scenario raises (@SCN-LNT-018) — the characteristic its
237
- * CONFIGURED ROW names, once.
238
- *
239
- * THE TAG NAMES THE AXIS AND THE ROW NAMES THE SUBJECT. A bare characteristic tag answered both at
240
- * once; the tier tags answer only the first, and nobody mints `@unit-parser`. So a converted
241
- * scenario carries `@fitness` alone and the characteristic is looked up by the scenario's own
242
- * `@SCN` — which is the row's KEY, so a row cannot name one scenario and be read against another.
243
- *
244
- * NOT A SECOND OBLIGATION SHAPE. What comes back is the same
245
- * `{ qualityCheck: "lint", staticCheck: <characteristic> }` the registered-tag arm raises, so the
246
- * pair key, the reconciler's static arm and the roll-up are untouched: only where the word came
247
- * from changed.
248
- *
249
- * NO REGISTRY HOP, and that is what conversion retires. An unconverted static check is discovered
250
- * as a script handle, and a handle does not know what it is for — hence the (now-retired)
251
- * registry, and hence the corpus lookup behind it. This route reads the citation off the row
252
- * rather than resolving it onto one.
253
- *
254
- * `seen` IS THE ARM ABOVE'S OWN SET, and shared deliberately. A check is owed once however it was
255
- * named: the axis tag can reach one scenario twice through its `Rule:` and its `Feature:`
256
- * (@SCN-LDG-020), and a row whose characteristic a bare tag on the same scenario already raised
257
- * owes nothing further. Two obligations for one characteristic would leave the second `missing`
258
- * for ever, since one run is one credit and can cite one `@SCN`.
259
- */
260
- function convertedFitnessObligationsOf(tags, fitnessChecks, seen, scnId) {
53
+ function convertedFitnessObligationsOf(tags) {
261
54
  if (!tags.includes(FITNESS_AXIS_TAG))
262
55
  return [];
263
- const row = fitnessChecks.get(scnId);
264
- if (row === undefined || seen.has(row.characteristic))
265
- return [];
266
- seen.add(row.characteristic);
267
- return [{ qualityCheck: "lint", staticCheck: row.characteristic }];
56
+ return [{ qualityCheck: "fitness" }];
268
57
  }
269
- /**
270
- * The scenarios ON the fitness axis that no configured row NAMES (@SCN-LNT-020) — a corpus that has
271
- * half-converted a check: the tag moved and the row was never written.
272
- *
273
- * IT RAISES NOTHING AND THAT IS NOT NEGOTIABLE. Such a scenario has said which axis it is on and
274
- * then said nothing about what it asserts; there is no characteristic to raise an obligation FOR,
275
- * and reaching for the nearest word is the near-match courtesy the portfolio roster already
276
- * refuses. So `convertedFitnessObligationsOf` above answers the empty list, and this reads the same
277
- * two facts — the axis tag, and the row's absence — to say WHO.
278
- *
279
- * THE RUN ALREADY REDS ON IT, through no rule of this function's. A converted check's scenario
280
- * carries the axis tag and its `@SCN` and nothing else, so a scenario no row names reconciles to
281
- * zero rows on BOTH sides and is out of balance through the degenerate `both-missing` item — canon's
282
- * row for exactly this profile (Scenario Exists, Evidence Obligation None, Evidence Observation
283
- * None). No outcome is minted here, and none is needed.
284
- *
285
- * WHAT IS ADDED IS THE SENTENCE. That degenerate item cannot say WHY: its own gloss is about a
286
- * scenario carrying no `@SCN`, and this one carries one. So the run NAMES these, count and id, where
287
- * it already names the other corpus-shape faults — facts only, no prescribed cure, and the reader
288
- * is left with the one remedy there is, which is to write the row.
289
- *
290
- * IT READS THE WALK IT IS HANDED rather than taking a source of its own, and it reads the same
291
- * `FITNESS_AXIS_TAG` and the same registry the obligation rule reads. A second walk would be free to
292
- * disagree about which scenario it is looking at, and a corpus naming one scenario while the rule
293
- * raised nothing for another is precisely the disagreement `parseTaggedScenarios` was extracted to
294
- * foreclose.
295
- *
296
- * NAMED ONCE however many of a scenario's effective tags name the axis (@SCN-LDG-020) — naming it
297
- * twice would put one remedy on the report twice and make the count say there are two
298
- * half-converted checks where there is one.
299
- */
300
- export function unconfiguredFitnessScenarios(scenarios, fitnessChecks) {
301
- const unconfigured = [];
302
- for (const scenario of scenarios) {
303
- if (!scenario.tags.includes(FITNESS_AXIS_TAG))
304
- continue;
305
- if (fitnessChecks.has(scenario.scnId))
306
- continue;
307
- if (!unconfigured.includes(scenario.scnId))
308
- unconfigured.push(scenario.scnId);
309
- }
310
- return unconfigured;
311
- }
312
- /**
313
- * THE CONFIGURED ROWS THE CORPUS CARRIES NO SCENARIO FOR (3F-3472, @SCN-LNT-027) — the mirror of
314
- * `unconfiguredFitnessScenarios` directly above, in MANIFEST order.
315
- *
316
- * THE RUN DOES NOT ALREADY RED ON IT, WHICH IS THE WHOLE DIFFERENCE BETWEEN THE TWO. Its mirror
317
- * adds only a sentence, because a scenario no row names already reconciles to zero rows on both
318
- * sides and is out of balance through the degenerate item. A row no scenario names raised NOTHING:
319
- * the obligations travel with the scenarios, so a row with no scenario contributed a characteristic
320
- * nobody asked for and the run read balanced over a check that was declared and never specified.
321
- * `double-entry-manifesto.md` names that shape exactly — a ledger catches a credit that never
322
- * arrived and is blind to a debit that was never raised.
323
- *
324
- * IT READS THE WALK IT IS HANDED, for its mirror's reason: a second walk would be free to disagree
325
- * about which scenarios the corpus holds, and a row raised against a corpus the obligations were
326
- * not taken from is the phantom-row fault (@SCN-LNT-009) reached from the manifest side.
327
- *
328
- * EVERY `@SCN`-CARRYING SCENARIO COUNTS, NOT THE `@fitness` ONES ALONE. The claim is that the
329
- * corpus carries no scenario for the row — so a scenario carrying the row's code and saying nothing
330
- * about the fitness axis is still a scenario somebody wrote under that code, and minting a debit
331
- * beside it would report a check nobody has specified where one has been started.
332
- */
333
- export function unspecifiedFitnessRows(scenarios, fitnessChecks) {
334
- const carried = new Set(scenarios.map((scenario) => scenario.scnId));
335
- const unspecified = [];
336
- for (const [scnId, row] of fitnessChecks) {
337
- if (carried.has(scnId))
338
- continue;
339
- unspecified.push({ scnId, characteristic: row.characteristic });
340
- }
341
- return unspecified;
342
- }
343
- /**
344
- * Derive a scenario's evidence obligations from its EFFECTIVE tags — its own PLUS everything it
345
- * inherits from its `Feature:` and any enclosing `Rule:` (@SCN-LDG-020). Unchanged in substance
346
- * from the tag-block reading it replaces; what changed is WHICH tags reach it.
347
- */
348
- function obligationsFromTags(tags, deferralTags, checkTags, scnId, fitnessChecks) {
58
+ function obligationsFromTags(tags, deferralTags) {
349
59
  const evidenceObligations = [];
350
60
  const seenQualityChecks = new Set();
351
61
  const seenPending = new Set();
352
- const seenChecks = new Set();
353
62
  for (const t of tags) {
354
- // A `<quality-check>pending` tag derives a DEFERRED, one-sided obligation
355
- // `{ qualityCheck, pending: true }` (no `staticCheck` payload). Tracked in its own set so
356
- // it is neither blocked by nor blocks a bare tier of the same quality-check, and
357
- // recognised SEPARATELY from the bare tier tag (the `pending` suffix is significant).
358
63
  const pendingCheck = pendingQualityCheck(t);
359
64
  if (pendingCheck && !seenPending.has(pendingCheck)) {
360
65
  seenPending.add(pendingCheck);
@@ -368,30 +73,9 @@ function obligationsFromTags(tags, deferralTags, checkTags, scnId, fitnessChecks
368
73
  continue;
369
74
  }
370
75
  }
371
- // The FITNESS obligations (@SCN-LNT-006), raised after the tier arms and BEFORE the deferral pass
372
- // below, so a deferred fitness scenario defers like any other rather than escaping through a later
373
- // arm. `seenChecks` keeps a check from being owed twice however many of a scenario's effective
374
- // tags name it.
375
- evidenceObligations.push(...fitnessObligationsOf(tags, checkTags, seenChecks),
376
- // The CONVERTED route (@SCN-LNT-018), on the same `seen` set and after the registered-tag arm:
377
- // a characteristic is owed once whichever of the two named it.
378
- ...convertedFitnessObligationsOf(tags, fitnessChecks, seenChecks, scnId));
379
- // SCENARIO-SCOPE community deferral (@SCN-PND-016): when the tag block carries a
380
- // RECOGNISED community deferral tag (a bare tag ∈ the injected `deferralTags` set —
381
- // empty by default; the app passes its starter policy ∪ config), the whole scenario is
382
- // deferred: mark EVERY obligation `pending: true`, overriding its observation-derived
383
- // outcome. Applied AFTER the
384
- // obligation list is built, so it composes with the `<qc>pending` recognition and covers
385
- // every obligation kind (runtime tiers AND the fitness ones). Idempotent on an
386
- // already-pending obligation.
76
+ evidenceObligations.push(...convertedFitnessObligationsOf(tags));
387
77
  if (tags.some((t) => deferralTags.includes(t))) {
388
78
  if (evidenceObligations.length === 0) {
389
- // INTERPRETATION 2 (@SCN-PND-022): a deferred scenario raising ZERO obligations (a
390
- // bare `@wip` — no evidence tag) synthesises ONE scenario-scope pending obligation:
391
- // `{ pending: true }` with NO `qualityCheck` (undefined = scenario-scope) and no `staticCheck`.
392
- // The reconcile partition routes it to one `qualityCheck`-less Pending Item, so the
393
- // scenario is deferred (pending) — the both-missing guard (fires only on zero pending
394
- // items) leaves it balanced, not the degenerate both-missing row.
395
79
  evidenceObligations.push({ pending: true });
396
80
  }
397
81
  else {
@@ -401,15 +85,6 @@ function obligationsFromTags(tags, deferralTags, checkTags, scnId, fitnessChecks
401
85
  }
402
86
  return evidenceObligations;
403
87
  }
404
- /**
405
- * Parse one feature source into cucumber's own AST, or THROW.
406
- *
407
- * An UNPARSEABLE source never yields an empty corpus. Silently returning zero scenarios is the
408
- * precise shape of the false-green this tool exists to prevent: an empty debit side balances against
409
- * anything. The app refuses an unreadable feature file at the ingest edge long before this
410
- * (@SCN-CLI-016: exit 2, halting before any reconcile), so the throw is unreachable in a real run —
411
- * it is the floor that keeps a future caller from re-opening the hole quietly.
412
- */
413
88
  function parseFeatureDocument(source) {
414
89
  const parser = new Parser(new AstBuilder(IdGenerator.uuid()), new GherkinClassicTokenMatcher());
415
90
  try {
@@ -417,150 +92,38 @@ function parseFeatureDocument(source) {
417
92
  }
418
93
  catch (err) {
419
94
  const message = err instanceof Error ? err.message : String(err);
420
- throw new Error(`The feature source is not valid Gherkin, so no scenario corpus can be read from it. ` +
421
- `Reconciling an empty corpus would balance against anything — so this fails loudly ` +
422
- `rather than silently. Cause: ${message}`);
423
- }
424
- }
425
- /** A blank line, or one carrying only a `#` comment — what a block's extent is trimmed back over. */
426
- const BLANK_OR_COMMENT = /^\s*(?:#.*)?$/;
427
- /**
428
- * Where a Gherkin block STARTS: its first own tag line if it has one, else its keyword line. Own
429
- * tags only — a tag inherited from an enclosing `Rule:` or from the `Feature:` sits in another
430
- * block's text, and claiming it here would give two blocks the same lines.
431
- */
432
- function blockStart(block) {
433
- return Math.min(block.location.line, ...(block.tags ?? []).map((t) => t.location.line));
434
- }
435
- /**
436
- * Every block start in the document, ascending — the BOUNDARIES one block's text ends at. Untagged
437
- * scenarios count: a block's extent has to stop at the next block whether or not that block is one
438
- * anybody can name.
439
- */
440
- function collectBlockStarts(children, starts) {
441
- for (const child of children) {
442
- if (child.rule) {
443
- starts.push(blockStart(child.rule));
444
- collectBlockStarts(child.rule.children, starts);
445
- continue;
446
- }
447
- if (child.background)
448
- starts.push(blockStart(child.background));
449
- if (child.scenario)
450
- starts.push(blockStart(child.scenario));
95
+ throw new Error(CORE_MESSAGES[CoreMessage.FeatureSourceNotGherkin](message));
451
96
  }
452
97
  }
453
- /**
454
- * Every block start in the document, ASCENDING — the boundaries `blockEnd` measures against. Read
455
- * off the SAME parse the tags come from (@SCN-SSM-010): one Gherkin parse, two walks of its
456
- * children, never a second read of the source.
457
- */
458
- function documentBlockStarts(document) {
459
- const starts = [];
460
- collectBlockStarts((document.feature?.children ?? []), starts);
461
- return starts.sort((a, b) => a - b);
462
- }
463
- /**
464
- * Where the block starting at `start` ENDS: the line before the next boundary, or EOF, trimmed back
465
- * over trailing blank and comment lines so the gap between two scenarios belongs to neither.
466
- */
467
- function blockEnd(start, starts, lines) {
468
- const next = starts.find((boundary) => boundary > start);
469
- let end = Math.min(next !== undefined ? next - 1 : lines.length, lines.length);
470
- while (end > start && BLANK_OR_COMMENT.test(lines[end - 1] ?? ""))
471
- end -= 1;
472
- return end;
473
- }
474
- /**
475
- * Read every `@SCN`-carrying scenario with its EFFECTIVE tags — the corpus walk `parseScenarios`
476
- * is built on, and the same walk any other whole-corpus tag question is answered from.
477
- *
478
- * The obligation rule is deliberately NOT applied here: what a scenario TAGS and what it OWES are
479
- * different questions, and the second is `obligationsFromTags`'. Keeping them apart is what lets
480
- * the citation seam ask the first without inheriting a reading of the second.
481
- *
482
- * WHY THE WALK IS THE AST'S AND NOT A SCAN'S. This was a hand-rolled TAG-LINE SCAN that saw only
483
- * the contiguous tag block directly above a `Scenario:`. Gherkin does not work that way — a
484
- * scenario INHERITS the tags of its `Feature:` and of any enclosing `Rule:`. Two bugs followed,
485
- * and both were false-greens:
486
- *
487
- * UNDER-READ. An evidence tier hoisted to the Feature/Rule line — idiomatic, valid Gherkin,
488
- * exactly what an author does with a tier shared by every scenario beneath — was INVISIBLE. The
489
- * obligation was never RAISED, so its missing evidence could never reconcile `missing`, and the
490
- * run read BALANCED (exit 0) while cucumber named a tier nothing proved. Unlike the corrupt-
491
- * file false-green (3F-1767), this one fires on WELL-WRITTEN files — which makes it likelier.
492
- *
493
- * OVER-READ. Any non-tag line flushed the accumulated block, so a tag block above a `Rule:` was
494
- * emitted AS IF it were a scenario. The corpus did not merely miss scenarios — it INVENTED them.
495
- *
496
- * EVERY tag inherits, `@SCN` included: parity with cucumber is the goal, and excluding one would
497
- * invent a rule cucumber does not have. A hoisted `@SCN` therefore gives every scenario beneath it
498
- * the same id — a corpus-authoring fault, but a VISIBLE one (whether it should red is a deferred
499
- * policy question, 3F-1774's sibling).
500
- *
501
- * An UNPARSEABLE source THROWS, from `parseFeatureDocument` — it never yields an empty corpus, for
502
- * the reason recorded there.
503
- */
504
98
  export function parseTaggedScenarios(source) {
505
- const document = parseFeatureDocument(source);
99
+ const { feature } = parseFeatureDocument(source);
100
+ if (feature === undefined)
101
+ return [];
506
102
  const tagged = [];
507
- // The parser tokenises, so no whitespace ever reaches `tag.name` and this was never a defect —
508
- // it takes the shared reading anyway so the count of readings stays at one (@SCN-TRM-001).
509
103
  const bare = (tags) => tags.map((t) => bareTerm(t.name));
510
- const featureTags = bare(document.feature?.tags ?? []);
511
- const lines = source.split(/\r?\n/);
512
- const starts = documentBlockStarts(document);
104
+ const featureTags = bare(feature.tags);
513
105
  const collect = (children, inherited) => {
514
106
  for (const child of children) {
515
107
  if (child.rule) {
516
- // A Rule's tags cascade to every scenario beneath it — cucumber applies them, so we must.
517
108
  collect(child.rule.children, [...inherited, ...bare(child.rule.tags)]);
518
109
  continue;
519
110
  }
520
111
  if (!child.scenario)
521
112
  continue;
522
- // The EFFECTIVE tag set: the scenario's OWN tags, then everything it inherits from its Rule
523
- // and Feature. This is the whole fix — the old scan saw only the first of the three. Own
524
- // tags lead so a scenario's obligations read in the order its tags name them, and a
525
- // file using NO inheritance yields a byte-identical corpus to the one the scan produced.
526
113
  const effective = [...bare(child.scenario.tags), ...inherited];
527
114
  const scnTag = effective.find((t) => SCN_CODE.test(t));
528
115
  if (scnTag === undefined)
529
116
  continue;
530
- const startLine = blockStart(child.scenario);
531
- tagged.push({
532
- scnId: scnTag,
533
- tags: effective,
534
- startLine,
535
- endLine: blockEnd(startLine, starts, lines),
536
- });
117
+ tagged.push({ scnId: scnTag, tags: effective, name: child.scenario.name });
537
118
  }
538
119
  };
539
- collect((document.feature?.children ?? []), featureTags);
120
+ collect(feature.children, featureTags);
540
121
  return tagged;
541
122
  }
542
- /**
543
- * Parse the SCENARIO CORPUS — the ledger's DEBIT side — from the REAL Gherkin AST (@SCN-LDG-020,
544
- * 3F-1775), the same parser cucumber uses. So the scenarios spec-controller reconciles carry
545
- * EXACTLY the tags cucumber gives them: one reading of the file, not two.
546
- *
547
- * The corpus walk is `parseTaggedScenarios`'; this is the OBLIGATION rule applied over it. An
548
- * unparseable source still THROWS from the walk rather than yielding an empty corpus.
549
- *
550
- * `checkTags` — the registry's bare check tags (@SCN-LNT-006) — is ADDITIVE and defaults to none, so
551
- * `parseScenarios` keeps its place on the v1 barrel and every existing caller
552
- * reads exactly the corpus it read before. A target that has registered nothing raises no fitness
553
- * obligations, which is what lets the bare-tag reading land ahead of the corpus sweep that uses it.
554
- *
555
- * `fitnessChecks` — the target's CONFIGURED ROWS (@SCN-LNT-018) — is trailing and optional for the
556
- * same reason, and carries the scenario's own `scnId` into the obligation rule: a converted check's
557
- * characteristic is keyed by the row it is owed on, so the rule cannot be applied to a tag set
558
- * alone. Empty by default, so a target that has converted nothing raises nothing on this route.
559
- */
560
- export function parseScenarios(source, deferralTags = [], checkTags = [], fitnessChecks = new Map()) {
123
+ export function parseScenarios(source, deferralTags = []) {
561
124
  return parseTaggedScenarios(source).map((scenario) => ({
562
125
  scnId: scenario.scnId,
563
- evidenceObligations: obligationsFromTags(scenario.tags, deferralTags, checkTags, scenario.scnId, fitnessChecks),
126
+ evidenceObligations: obligationsFromTags(scenario.tags, deferralTags),
564
127
  }));
565
128
  }
566
129
  //# sourceMappingURL=scenarios.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scenarios.js","sourceRoot":"","sources":["../../src/parse/scenarios.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scenarios.js","sourceRoot":"","sources":["../../src/parse/scenarios.ts"],"names":[],"mappings":"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"}