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

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 +191 -0
  35. package/dist/domain/messages.d.ts.map +1 -0
  36. package/dist/domain/messages.js +279 -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 +12 -38
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +6 -86
  77. package/dist/index.js.map +1 -1
  78. package/dist/internal.d.ts +3 -25
  79. package/dist/internal.d.ts.map +1 -1
  80. package/dist/internal.js +3 -93
  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 +3 -151
  98. package/dist/parse/checkScriptsRunInCI.d.ts.map +1 -1
  99. package/dist/parse/checkScriptsRunInCI.js +5 -143
  100. package/dist/parse/checkScriptsRunInCI.js.map +1 -1
  101. package/dist/parse/ciStepRecord.d.ts +2 -117
  102. package/dist/parse/ciStepRecord.d.ts.map +1 -1
  103. package/dist/parse/ciStepRecord.js +12 -218
  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 +0 -58
  108. package/dist/parse/commandRuns.js.map +1 -1
  109. package/dist/parse/cucumber.d.ts +0 -52
  110. package/dist/parse/cucumber.d.ts.map +1 -1
  111. package/dist/parse/cucumber.js +37 -143
  112. package/dist/parse/cucumber.js.map +1 -1
  113. package/dist/parse/discoveryScope.d.ts +0 -45
  114. package/dist/parse/discoveryScope.d.ts.map +1 -1
  115. package/dist/parse/discoveryScope.js +0 -55
  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 +0 -63
  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 +11 -447
  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 +0 -45
  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 +1 -81
  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,227 +1,76 @@
1
- /**
2
- * The TARGET's `specController.*` configuration, read into the rows and mints the
3
- * reconciler takes — the `resolve*` family, moved here from the app's ingest edge (3F-3087).
4
- *
5
- * WHY THEY LIVE IN THE ENGINE. Every one of them is a pure function of a manifest object
6
- * somebody else already read off disk, and every one of them is the ONE reading of the key it
7
- * names — `fitnessChecksOf` and `bareTerm` are both core's, so the reader and the
8
- * thing it reads through belonged on the same side of the package boundary. Sitting at the app
9
- * edge they were the reason a PUBLISHED module imported core's unpublished `/internal` subpath,
10
- * which is the fault 3F-3086 repairs; nothing about reading a parsed manifest ever needed the
11
- * edge that produced it.
12
- *
13
- * WHAT THE EDGE STILL OWES THEM, AND WHY IT IS A PARAMETER. One of these readings depends on
14
- * something the engine must not know: the deferral-tag STARTER SET is product policy the
15
- * application layer single-sources (`DEFAULT_DEFERRAL_TAGS`). It arrives as an argument, as data,
16
- * so the engine keeps knowing nothing about files (`lint:boundaries`' `core-imports-io` rule,
17
- * which was @SCN-EPG-001's `io-import` arm until 3F-3437; and 3F-2841's pattern: a project-owned
18
- * term arrives as an input).
19
- *
20
- * DEFENSIVE THROUGHOUT, AND THAT IS THE FAMILY'S STANCE RATHER THAN LOCAL CHOICES PER RESOLVER.
21
- * Config is data from outside: a missing, non-object or array-shaped value resolves EMPTY, and a
22
- * malformed entry is dropped by the reading function it is handed to rather than thrown. A check
23
- * that throws on a typo produces no verdict at all.
24
- */
25
1
  import { bareTerm } from "../lib/bareTerm.js";
26
- import { fitnessChecksOf } from "../domain/fitnessChecks.js";
27
- // THE FOUR CANON TIERS, read from the ledger's own enumeration rather than restated here
28
- // (@SCN-USG-019). A second list of the same four would agree by coincidence, and this axis's
29
- // whole argument is that a list of names is the drift.
30
2
  import { RUNTIME_QUALITY_CHECKS } from "../domain/ledger.js";
31
- /** Whether a value read out of a manifest is a block of named fields, rather than a list or scalar. */
32
3
  function isBlock(value) {
33
4
  return typeof value === "object" && value !== null && !Array.isArray(value);
34
5
  }
35
- /**
36
- * The steps the TARGET names NON-CHECKS (@SCN-USG-015, 3F-3343) — `specController.notChecks`, read
37
- * as the fully-qualified `<workflow file>:<job id>:<step name>` entries the target wrote.
38
- *
39
- * IT IS THE CONSUMER'S OWN LIST, and that is the whole reason it may exist at all. Not everything
40
- * that is not a behavioural runner is a fitness check — a checkout, a dependency install, a deploy
41
- * — and this axis's standing rule is that a list of check NAMES is the drift. A list of the
42
- * consumer's own STEPS is the opposite thing: it is about their pipeline, it is written once, and
43
- * nothing in this tree has an opinion about what is on it.
44
- *
45
- * The seventh of this family's `specController.*` resolvers, and defensive like the six above it:
46
- * a missing or non-array value resolves EMPTY and a non-string entry is dropped rather than
47
- * thrown. Deduplicated, as the configured-static-check list beside it is, so a target that wrote
48
- * one line twice is reported one line — the account below is per ENTRY, and the same entry twice
49
- * is one thing the consumer said.
50
- *
51
- * WHAT AN ENTRY MEANS IS NOT DECIDED HERE. This reader takes the list off the manifest; matching it
52
- * against a pipeline, and saying which entries matched nothing, is `parse/stepExclusions`.
53
- */
6
+ const isTier = (key) => RUNTIME_QUALITY_CHECKS.includes(key);
7
+ const isRunner = (value) => typeof value === "string" || value === null;
8
+ const isListEntry = (value) => typeof value === "string";
54
9
  export function resolveNotChecks(packageJson) {
55
10
  const configured = packageJson.specController?.notChecks;
56
11
  if (!Array.isArray(configured))
57
12
  return [];
58
- return [...new Set(configured.filter((entry) => typeof entry === "string"))];
13
+ return [...new Set(configured.filter(isListEntry))];
59
14
  }
60
- /**
61
- * Resolve the recognised deferral-tag set for the target (@SCN-PND-021) — the app's single-sourced
62
- * starter set EXTENDED by the target `package.json`'s `specController.deferralTags`. Config
63
- * EXTENDS, never replaces: a project cannot un-recognise a built-in (`@wip` always defers).
64
- * Configured tags are bare names, `@`-stripped, consistent with the starter set; non-string /
65
- * non-array config is ignored defensively. `parseScenarios` then takes the union as its injected
66
- * `deferralTags` param.
67
- *
68
- * THE STARTER SET ARRIVES AS AN ARGUMENT AND IS NOT THE ENGINE'S TO HOLD (3F-3087). Which
69
- * community tags defer is product policy — an evolvable list of strings the application layer
70
- * single-sources as `DEFAULT_DEFERRAL_TAGS` — and a core-held copy would be a second statement of
71
- * it. So the union is computed here, where the config read is, and the policy is handed in.
72
- */
73
- export function resolveDeferralTags(packageJson,
74
- /** The application layer's starter set — the built-ins a target's config may only extend. */
75
- starterTags) {
15
+ export function resolveDeferralTags(packageJson, starterTags) {
76
16
  const configured = packageJson.specController?.deferralTags;
77
17
  const extras = Array.isArray(configured)
78
18
  ? configured
79
- .filter((tag) => typeof tag === "string")
80
- // Through the ONE reading of what a term bare is (@SCN-TRM-001). This port had no trim at
81
- // all, so `"@wip "` failed as well as `" @wip"`, and a term that is nothing but
82
- // whitespace and a sigil is dropped here as an empty one already is.
19
+ .filter(isListEntry)
83
20
  .map(bareTerm)
84
21
  .filter((tag) => tag !== "")
85
22
  : [];
86
- // Union: the starter set FIRST (extends, never replaces — a project cannot un-recognise a
87
- // built-in), then the configured extras; de-duplicated to keep the set clean.
88
23
  return [...new Set([...starterTags, ...extras])];
89
24
  }
90
- /**
91
- * The TARGET's CONFIGURED FITNESS ROWS (@SCN-LNT-018) — `specController.fitnessChecks`, read as
92
- * `@SCN → the characteristic that scenario asserts` through the engine's own `fitnessChecksOf`.
93
- *
94
- * THE DEBIT SIDE OF A CONVERTED CHECK. A converted scenario carries `@fitness` and nothing about
95
- * its subject, so the characteristic it owes comes from here — and from the row whose `scn` is that
96
- * scenario's own, which is what removes the registry hop an unconverted static check needs.
97
- *
98
- * IT IS THE TARGET'S, for the reason the check registry and the ceilings are (@SCN-LNT-005): a
99
- * characteristic means what the target says it means, and a row resolved from this tool's own
100
- * manifest would put an obligation on a target's books under a word it never wrote.
101
- *
102
- * The fifth of this family's `specController.*` resolvers, and defensive like the four above it: a
103
- * missing or wrongly-shaped config resolves EMPTY, and a malformed row is dropped by
104
- * `fitnessChecksOf` rather than thrown. There is no starter set: a target that has converted
105
- * nothing owes nothing on this route, which is what keeps the reading inert on an unswept corpus.
106
- */
107
- export function resolveFitnessChecks(packageJson) {
108
- return fitnessChecksOf(packageJson.specController?.fitnessChecks);
109
- }
110
- /**
111
- * The TARGET's BEHAVIOURAL RUNNERS (@SCN-USG-011, 3F-3343) — `specController.runners`, read as
112
- * `tier → the name of the binary that tier's suite runs under`.
113
- *
114
- * THE SMALL CLOSED THING, NAMED, so the open one can be inferred. The set of names a quality check
115
- * might go by is unbounded and belongs to the consumer; the set of behavioural runners is one per
116
- * tier tag and the tiers are canon. Naming the closed set and deriving the rest is the move the
117
- * `@fitness` collapse already made one level in (3F-3139), and it cannot go stale by omission.
118
- *
119
- * IT IS THE TARGET'S, for the reason the check registry and the ceilings are (@SCN-LNT-005): which
120
- * command runs a repository's unit suite is a fact about that repository, and a runner resolved
121
- * from this tool's own manifest would answer for a pipeline this run never looked at.
122
- *
123
- * The sixth of this family's `specController.*` resolvers, and defensive like the five above it: a
124
- * missing, non-object or array-shaped config resolves EMPTY, and an entry whose value is neither a
125
- * runner's NAME nor `null` is dropped rather than thrown. A manifest naming no runners is not an
126
- * error — it is a `new-client`, which is the state this axis is sold on.
127
- *
128
- * A NULL IS KEPT, AND IT IS THE THIRD STATE (@SCN-USG-016, 3F-3343). `"performance": null` is
129
- * something the target SAID — we have no performance suite — and a tier the block omits is
130
- * something it never said. Dropping the null folds the first into the second and loses a fact we
131
- * were given, in the one direction nothing downstream can recover: after the fold, silence and a
132
- * stated absence are indistinguishable. Nothing else in this reader's contract moves — a null
133
- * recognises no step, exactly as a missing key recognises none — so the ONLY place the two can be
134
- * told apart is this return value and the report rendered off it.
135
- *
136
- * THE KEY SET IS CLOSED, AND THE PARTITION IS THIS READER'S (@SCN-USG-019, 3F-3343). The block is
137
- * keyed by TIER and the tiers are canon, which is exactly what makes the whole inversion possible:
138
- * the closed set is named because it is enumerable, and the open one is inferred from what is left.
139
- * A key outside the four is therefore not a runner for anything, and both obvious answers to it are
140
- * wrong. HONOURING it is the smuggling the closure forbids — `"lint": "eslint"` is a consumer taking
141
- * their own checks out of discovery one key at a time, and it reinstates the silence this axis
142
- * exists to remove. DROPPING it silently is the same class of fault one layer along: the consumer
143
- * wrote something, believes it took effect, and has no line anywhere to correct it from. So the key
144
- * is partitioned out of the runners AND handed back to be named, and the run is not aborted over it.
145
- *
146
- * THE FOUR TIERS ARE READ, NEVER RESTATED. `RUNTIME_QUALITY_CHECKS` is the ledger's own enumeration
147
- * of the runtime tiers; a second copy here would agree with it by coincidence, and a list of names
148
- * is the drift this ticket is about.
149
- *
150
- * THE PARTITION IS ON THE KEY AND THE DEFENSIVE DROP IS ON THE VALUE, and the two are different
151
- * questions kept apart. A canon tier whose value is neither a runner's NAME nor `null` is malformed
152
- * config and is dropped, which is this family's stance about data from outside. A key that is not a
153
- * tier at all is not malformed — there is no tier for any value of it to name a runner for — so its
154
- * value is beside the point and the key is the fact worth reporting, whatever it was set to.
155
- */
156
25
  export function resolveRunners(packageJson) {
157
26
  const configured = packageJson.specController?.runners;
158
27
  if (!isBlock(configured))
159
28
  return { tiers: {}, unrecognisedKeys: [] };
160
- const isTier = (key) => RUNTIME_QUALITY_CHECKS.includes(key);
161
29
  return {
162
- tiers: Object.fromEntries(Object.entries(configured).filter((entry) => isTier(entry[0]) && (typeof entry[1] === "string" || entry[1] === null))),
30
+ tiers: Object.fromEntries(Object.entries(configured).filter((entry) => isTier(entry[0]) && isRunner(entry[1]))),
163
31
  unrecognisedKeys: Object.keys(configured).filter((key) => !isTier(key)),
164
32
  };
165
33
  }
166
- /**
167
- * THE specController.* KEYS THIS READER HAS RETIRED (@SCN-USG-021, @SCN-USG-022, @SCN-USG-023) —
168
- * the top-level keys a manifest carries whose reading this tool has removed, in the order the
169
- * manifest wrote them.
170
- *
171
- * NAMED, NOT SILENTLY GONE. Retiring a route is not the same act as never having had one: a
172
- * consumer who wrote `checkRegistry` once, when it was read, believes it still routes their
173
- * checks. Ceasing to read it without saying so leaves them holding a manifest that no longer
174
- * does what they think, with nothing on the report to correct it from — the same fault as a
175
- * dropped step, reached from the retirement side rather than the discovery side.
176
- *
177
- * APPEND-ONLY, the family's own append-only key set (RUNTIME_QUALITY_CHECKS beside it). A key
178
- * retires once and is never re-read; the set only grows as this reader retires more of them
179
- * (`checkRegistry` first, 3F-3398; `staticChecks` second, 3F-3399 — the tiebreak
180
- * `parse/runningStaticChecks.ts`'s `handleOf` used to settle among several invoked scripts,
181
- * 3F-3396 deleted; `thresholds` third, 3F-3517 — the ceilings the measured axis held a scenario
182
- * to, 3F-3516 deleted).
183
- *
184
- * DEFENSIVE LIKE THE READERS ABOVE IT: a missing or non-object `specController` names no
185
- * retired key, never throws.
186
- */
187
- const RETIRED_SPEC_CONTROLLER_KEYS = ["checkRegistry", "staticChecks", "thresholds"];
188
- /**
189
- * THE BAR A CONFIGURED ROW STILL CARRIES (@SCN-LNT-035) — the row-level keys this reader has
190
- * retired, append-only like the top-level set above. Nothing reads a row's bar since 3F-3510: a
191
- * row is credited by its own step's outcome, so a bar left on it holds the check to nothing. A
192
- * `mutationGate` is a value of `atLeast`, so the key it sits under is what names it.
193
- *
194
- * NAMED WITH ITS ROW, `fitnessChecks[<@SCN>].<key>`, because a row-level key alone says nothing a
195
- * consumer could find it by. A row stating no usable `@SCN` names no bar: the row reader drops it
196
- * whole, and there is no handle to name its bar by.
197
- */
198
- const RETIRED_ROW_KEYS = ["atLeast", "atMost"];
199
- function retiredRowKeysOf(rows) {
200
- if (!Array.isArray(rows))
201
- return [];
202
- return rows.flatMap((row) => {
203
- if (!isBlock(row) || typeof row["scn"] !== "string")
204
- return [];
205
- const scnId = bareTerm(row["scn"]);
206
- if (scnId === "")
207
- return [];
208
- return Object.keys(row)
209
- .filter((key) => RETIRED_ROW_KEYS.includes(key))
210
- .map((key) => `fitnessChecks[${scnId}].${key}`);
211
- });
34
+ function kindOf(value) {
35
+ if (value === null)
36
+ return "null";
37
+ if (Array.isArray(value))
38
+ return "a list";
39
+ if (typeof value === "object")
40
+ return "an object";
41
+ return `a ${typeof value}`;
212
42
  }
213
- /**
214
- * ONE ACCOUNT FOR BOTH KINDS, in the order the manifest wrote them: a retired top-level key names
215
- * itself, and `fitnessChecks` names each bar its rows still carry.
216
- */
217
- export function resolveRetiredKeys(packageJson) {
218
- const configured = packageJson.specController;
219
- if (!isBlock(configured))
220
- return [];
221
- return Object.entries(configured).flatMap(([key, value]) => {
222
- if (key === "fitnessChecks")
223
- return retiredRowKeysOf(value);
224
- return RETIRED_SPEC_CONTROLLER_KEYS.includes(key) ? [key] : [];
225
- });
43
+ const wrongKind = (entry, value, reads) => ({
44
+ entry,
45
+ is: kindOf(value),
46
+ reads,
47
+ });
48
+ function wrongKindsInList(value, at) {
49
+ if (!Array.isArray(value))
50
+ return [wrongKind(at, value, "a list")];
51
+ return value.flatMap((entry, i) => (isListEntry(entry) ? [] : [wrongKind(`${at}[${i}]`, entry, "a string")]));
52
+ }
53
+ function wrongKindsInRunners(value, at) {
54
+ if (!isBlock(value))
55
+ return [wrongKind(at, value, "an object")];
56
+ return Object.entries(value)
57
+ .filter(([key, runner]) => isTier(key) && !isRunner(runner))
58
+ .map(([key, runner]) => wrongKind(`${at}.${key}`, runner, "a string or null"));
59
+ }
60
+ const BLOCK_READS = {
61
+ runners: wrongKindsInRunners,
62
+ notChecks: wrongKindsInList,
63
+ deferralTags: wrongKindsInList,
64
+ };
65
+ export function configurationNotRead(packageJson) {
66
+ const block = packageJson.specController;
67
+ if (block === undefined)
68
+ return { wrongKinds: [], unknownKeys: [] };
69
+ if (!isBlock(block))
70
+ return { wrongKinds: [wrongKind("specController", block, "an object")], unknownKeys: [] };
71
+ return {
72
+ unknownKeys: Object.keys(block).filter((key) => !Object.hasOwn(BLOCK_READS, key)),
73
+ wrongKinds: Object.entries(block).flatMap(([key, value]) => Object.hasOwn(BLOCK_READS, key) ? BLOCK_READS[key](value, `specController.${key}`) : []),
74
+ };
226
75
  }
227
76
  //# sourceMappingURL=targetManifest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"targetManifest.js","sourceRoot":"","sources":["../../src/parse/targetManifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"targetManifest.js","sourceRoot":"","sources":["../../src/parse/targetManifest.ts"],"names":[],"mappings":"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"}
@@ -1,50 +1,8 @@
1
- /**
2
- * The `ingest/vitest` reader — one of the two named observed-evidence readers
3
- * (the embryonic adapters, deliberately not a registry in v1). Reads Vitest's
4
- * JSON reporter output and normalises each assertion that cites an @SCN id into
5
- * an EvidenceObservation at the `unit` level.
6
- *
7
- * The level is supplied by the CALLER, not inferred: the caller states the level this Vitest
8
- * source yields, and the reader stamps it — no Vitest⇒unit assumption baked into the parser. The
9
- * JS-ecosystem default (unit) is set at the CLI edge.
10
- *
11
- * The @SCN id is the bracketed `[SCN-<FFF>-<NNN>]` token carried in the test's
12
- * `describe`/`it` name (the bidirectional-link rule). The bracket is what makes it a
13
- * citation and not a mention: this module's regex used to match any SCN-shaped token
14
- * anywhere in the name, so fixture data and prose cross-references cited scenarios nobody
15
- * meant to cite (@SCN-LDG-033, 3F-2368). The form now lives in `lib/scnCitation.ts`,
16
- * shared with the scn-subissue gate's cite scan so one answer serves both readers.
17
- *
18
- * Vitest surfaces the assertion's OWN name as `assertionResults[].title` and its
19
- * ANCESTOR PATH (describe → it) as `fullName`;
20
- * the citation belongs to the assertion, so the reader reads the leaf's title FIRST and
21
- * falls back to the ancestor path only when the leaf does not self-cite — most-specific-
22
- * citation-wins (@SCN-LDG-016).
23
- *
24
- * The reader classifies THREE-WAY (@SCN-PND-015), uniform with the cucumber reader
25
- * (@SCN-PND-013): a `passed` assertion → a `passed` observation (satisfied); a `failed`
26
- * assertion → a `failed` observation (failing); an INCONCLUSIVE vitest status (`skipped`/`todo`,
27
- * and any status ∉ {passed, failed}) → the assertion is DROPPED (no observation), so its
28
- * obligation reconciles missing by absence — pending is never inferred from status. A skipped/todo
29
- * unit test is a GAP, not a failure.
30
- *
31
- * Parent: @SCN-LDG-001 (the foundation seam; balanced path).
32
- */
33
1
  import type { RuntimeQualityCheck, EvidenceObservation } from "../model.js";
34
- /** The minimal shape of Vitest's JSON reporter output this reader depends on. */
35
2
  export interface VitestJsonReport {
36
3
  testResults?: Array<{
37
- /** The test-file path — the locator for the evidenceObservations reconciliation. */
38
4
  name?: string;
39
- /**
40
- * The FILE-level status (@SCN-LDG-017) — previously read and discarded. A file that failed to
41
- * COLLECT reports `"failed"` here WITH a `message` and ZERO `assertionResults`: it errored
42
- * before naming a test. That pair (failed + zero assertions) is the collection-failure
43
- * signature the reader now emits as a `broken` observation. (A file whose tests merely FAILED
44
- * also reports `"failed"` here — but it carries assertions, so it is not broken.)
45
- */
46
5
  status?: string;
47
- /** The FILE-level error message a collection failure reports (@SCN-LDG-017). */
48
6
  message?: string;
49
7
  assertionResults?: Array<{
50
8
  fullName?: string;
@@ -53,23 +11,5 @@ export interface VitestJsonReport {
53
11
  }>;
54
12
  }>;
55
13
  }
56
- /**
57
- * Parse a Vitest JSON report into observed results at the CALLER-SUPPLIED level. One result per
58
- * EMITTED assertion: those carrying an @SCN id cite that scenario; those with NO id emit a
59
- * null-scnId credit (@SCN-LDG-007 — previously DROPPED). A null-scnId credit cites no scenario,
60
- * so the reconciler folds it into the SUSPENSE row. Every result carries its test-file locator.
61
- *
62
- * THREE-WAY classification (@SCN-PND-015), uniform with the cucumber reader (@SCN-PND-013) —
63
- * pending is NEVER inferred from status:
64
- * - `passed` → a `passed` observation → satisfied.
65
- * - `failed` → a `failed` observation → failing.
66
- * - otherwise (`skipped`/`todo`, and any status ∉ {passed, failed}) → INCONCLUSIVE: an assertion
67
- * that RAN but proved nothing. Emit NOTHING — the evidence obligation then finds no matching
68
- * observation and reconciles missing BY ABSENCE.
69
- * Treating any non-pass-non-fail status as inconclusive keeps the reader robust to vitest's status
70
- * spelling (`skipped`/`todo`/`pending`). `EvidenceStatus` stays binary (no new status, no reconciler
71
- * change): the DROP is what realises inconclusive→missing. The uncited (null-scnId) SUSPENSE credit
72
- * is preserved for genuine passed/failed results — only inconclusive assertions are dropped.
73
- */
74
14
  export declare function parseVitestEvidenceObservations(report: VitestJsonReport, qualityCheck: RuntimeQualityCheck, root?: string): EvidenceObservation[];
75
15
  //# sourceMappingURL=vitest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vitest.d.ts","sourceRoot":"","sources":["../../src/parse/vitest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAI5E,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,oFAAoF;QACpF,IAAI,CAAC,EAAE,MAAM,CAAC;QACd;;;;;;WAMG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,gFAAgF;QAChF,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,gBAAgB,CAAC,EAAE,KAAK,CAAC;YACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB,CAAC,CAAC;KACJ,CAAC,CAAC;CACJ;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,gBAAgB,EACxB,YAAY,EAAE,mBAAmB,EACjC,IAAI,CAAC,EAAE,MAAM,GACZ,mBAAmB,EAAE,CA4DvB"}
1
+ {"version":3,"file":"vitest.d.ts","sourceRoot":"","sources":["../../src/parse/vitest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAI5E,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,gBAAgB,CAAC,EAAE,KAAK,CAAC;YACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB,CAAC,CAAC;KACJ,CAAC,CAAC;CACJ;AAED,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,gBAAgB,EACxB,YAAY,EAAE,mBAAmB,EACjC,IAAI,CAAC,EAAE,MAAM,GACZ,mBAAmB,EAAE,CA8BvB"}
@@ -1,81 +1,14 @@
1
- /**
2
- * The `ingest/vitest` reader — one of the two named observed-evidence readers
3
- * (the embryonic adapters, deliberately not a registry in v1). Reads Vitest's
4
- * JSON reporter output and normalises each assertion that cites an @SCN id into
5
- * an EvidenceObservation at the `unit` level.
6
- *
7
- * The level is supplied by the CALLER, not inferred: the caller states the level this Vitest
8
- * source yields, and the reader stamps it — no Vitest⇒unit assumption baked into the parser. The
9
- * JS-ecosystem default (unit) is set at the CLI edge.
10
- *
11
- * The @SCN id is the bracketed `[SCN-<FFF>-<NNN>]` token carried in the test's
12
- * `describe`/`it` name (the bidirectional-link rule). The bracket is what makes it a
13
- * citation and not a mention: this module's regex used to match any SCN-shaped token
14
- * anywhere in the name, so fixture data and prose cross-references cited scenarios nobody
15
- * meant to cite (@SCN-LDG-033, 3F-2368). The form now lives in `lib/scnCitation.ts`,
16
- * shared with the scn-subissue gate's cite scan so one answer serves both readers.
17
- *
18
- * Vitest surfaces the assertion's OWN name as `assertionResults[].title` and its
19
- * ANCESTOR PATH (describe → it) as `fullName`;
20
- * the citation belongs to the assertion, so the reader reads the leaf's title FIRST and
21
- * falls back to the ancestor path only when the leaf does not self-cite — most-specific-
22
- * citation-wins (@SCN-LDG-016).
23
- *
24
- * The reader classifies THREE-WAY (@SCN-PND-015), uniform with the cucumber reader
25
- * (@SCN-PND-013): a `passed` assertion → a `passed` observation (satisfied); a `failed`
26
- * assertion → a `failed` observation (failing); an INCONCLUSIVE vitest status (`skipped`/`todo`,
27
- * and any status ∉ {passed, failed}) → the assertion is DROPPED (no observation), so its
28
- * obligation reconciles missing by absence — pending is never inferred from status. A skipped/todo
29
- * unit test is a GAP, not a failure.
30
- *
31
- * Parent: @SCN-LDG-001 (the foundation seam; balanced path).
32
- */
33
1
  import { relativizeToRoot } from "../lib/portablePath.js";
34
2
  import { parseScnCitation } from "../lib/scnCitation.js";
35
- /**
36
- * Parse a Vitest JSON report into observed results at the CALLER-SUPPLIED level. One result per
37
- * EMITTED assertion: those carrying an @SCN id cite that scenario; those with NO id emit a
38
- * null-scnId credit (@SCN-LDG-007 — previously DROPPED). A null-scnId credit cites no scenario,
39
- * so the reconciler folds it into the SUSPENSE row. Every result carries its test-file locator.
40
- *
41
- * THREE-WAY classification (@SCN-PND-015), uniform with the cucumber reader (@SCN-PND-013) —
42
- * pending is NEVER inferred from status:
43
- * - `passed` → a `passed` observation → satisfied.
44
- * - `failed` → a `failed` observation → failing.
45
- * - otherwise (`skipped`/`todo`, and any status ∉ {passed, failed}) → INCONCLUSIVE: an assertion
46
- * that RAN but proved nothing. Emit NOTHING — the evidence obligation then finds no matching
47
- * observation and reconciles missing BY ABSENCE.
48
- * Treating any non-pass-non-fail status as inconclusive keeps the reader robust to vitest's status
49
- * spelling (`skipped`/`todo`/`pending`). `EvidenceStatus` stays binary (no new status, no reconciler
50
- * change): the DROP is what realises inconclusive→missing. The uncited (null-scnId) SUSPENSE credit
51
- * is preserved for genuine passed/failed results — only inconclusive assertions are dropped.
52
- */
53
3
  export function parseVitestEvidenceObservations(report, qualityCheck, root) {
54
4
  const results = [];
55
5
  for (const file of report.testResults ?? []) {
56
- // The test-file locator (the where-to-fix) — carried on every credit (ruling
57
- // Q5), made portable relative to the run root (verbatim when no root given).
58
6
  const locator = relativizeToRoot(file.name ?? "(unknown vitest file)", root);
59
- // BROKEN, NOT ABSENT (@SCN-LDG-017) — the COLLECTION FAILURE. A file that failed to collect
60
- // reports `status: "failed"` WITH a message and ZERO assertionResults: it errored before it
61
- // named a test. Walking `assertionResults[]` alone saw nothing to emit, so the scenario whose
62
- // proof lived here reconciled `missing` — indistinguishable from an unwritten test, and the
63
- // wrong remedy (write a test vs fix the harness). Emit ONE observation carrying the collection
64
- // failure: `broken: true`, the file locator (WHERE to fix), and the runner's message (WHAT
65
- // broke). It cites NO scenario (`scnId: null`) — a suite that named no test cites no @SCN — so
66
- // the reconciler posts it to the SUSPENSE row.
67
- //
68
- // The signature is the PAIR (failed + zero assertions), never file status alone: an ordinary
69
- // red run also reports `status: "failed"` at file level, but its assertions ARE named and
70
- // attributable, and already land as `failing` on the scenarios they cite (the boundary). A
71
- // green file with zero assertions is likewise not broken — nothing errored.
72
7
  const assertions = file.assertionResults ?? [];
73
8
  if (file.status === "failed" && assertions.length === 0) {
74
9
  results.push({
75
10
  qualityCheck,
76
11
  scnId: null,
77
- // `status` is structurally required and the runner did report `failed`; the FAIL-SAFE in
78
- // the reconciler checks `broken` BEFORE `status`, so this never reconciles as `failing`.
79
12
  status: "failed",
80
13
  locator,
81
14
  broken: true,
@@ -85,25 +18,12 @@ export function parseVitestEvidenceObservations(report, qualityCheck, root) {
85
18
  }
86
19
  for (const assertion of assertions) {
87
20
  const status = assertion.status;
88
- // THREE-WAY (@SCN-PND-015): drop any inconclusive assertion (status ∉ {passed, failed}) —
89
- // skipped/todo/pending/undefined proved nothing, so the obligation reconciles missing by
90
- // absence. Only genuine passed/failed emit (the guard narrows `status` to EvidenceStatus).
91
21
  if (status !== "passed" && status !== "failed")
92
22
  continue;
93
- // MOST-SPECIFIC-CITATION-WINS (@SCN-LDG-016): the citation belongs to the ASSERTION, and
94
- // the assertion's OWN name is `title`; `fullName` is the ancestor PATH (outermost describe
95
- // → innermost it). So read the leaf's own title FIRST and fall back to the ancestor path
96
- // only when the leaf does not self-cite. This preserves the "describe carries the bracket,
97
- // plain `it`s beneath" style (a bare leaf falls through to the describe's citation) while
98
- // letting a self-citing leaf OVERRIDE its ancestor. The retired first-match-on-
99
- // `fullName + " " + title` did the opposite: a grouping describe's citation SHADOWED a
100
- // self-citing child, so the leaf's scenario reconciled missing while the ancestor took a
101
- // spurious SECOND credit. Semantic, not positional — last-match on the concatenation would
102
- // misfire when a leaf's prose names a second scenario after its own.
103
23
  const scnId = parseScnCitation(assertion.title ?? "") ?? parseScnCitation(assertion.fullName ?? "");
104
24
  results.push({
105
25
  qualityCheck,
106
- scnId, // no BRACKETED @SCN → an uncited credit (SUSPENSE).
26
+ scnId,
107
27
  status,
108
28
  locator,
109
29
  });
@@ -1 +1 @@
1
- {"version":3,"file":"vitest.js","sourceRoot":"","sources":["../../src/parse/vitest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAyBzD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,+BAA+B,CAC7C,MAAwB,EACxB,YAAiC,EACjC,IAAa;IAEb,MAAM,OAAO,GAA0B,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;QAC5C,6EAA6E;QAC7E,6EAA6E;QAC7E,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,uBAAuB,EAAE,IAAI,CAAC,CAAC;QAC7E,4FAA4F;QAC5F,4FAA4F;QAC5F,8FAA8F;QAC9F,4FAA4F;QAC5F,+FAA+F;QAC/F,2FAA2F;QAC3F,+FAA+F;QAC/F,+CAA+C;QAC/C,EAAE;QACF,6FAA6F;QAC7F,0FAA0F;QAC1F,2FAA2F;QAC3F,4EAA4E;QAC5E,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,IAAI,EAAE,CAAC;QAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC;gBACX,YAAY;gBACZ,KAAK,EAAE,IAAI;gBACX,yFAAyF;gBACzF,yFAAyF;gBACzF,MAAM,EAAE,QAAQ;gBAChB,OAAO;gBACP,MAAM,EAAE,IAAI;gBACZ,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACjE,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;YAChC,0FAA0F;YAC1F,yFAAyF;YACzF,2FAA2F;YAC3F,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,QAAQ;gBAAE,SAAS;YACzD,yFAAyF;YACzF,2FAA2F;YAC3F,yFAAyF;YACzF,2FAA2F;YAC3F,0FAA0F;YAC1F,gFAAgF;YAChF,uFAAuF;YACvF,yFAAyF;YACzF,2FAA2F;YAC3F,qEAAqE;YACrE,MAAM,KAAK,GACT,gBAAgB,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,gBAAgB,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;YACxF,OAAO,CAAC,IAAI,CAAC;gBACX,YAAY;gBACZ,KAAK,EAAE,oDAAoD;gBAC3D,MAAM;gBACN,OAAO;aACR,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"vitest.js","sourceRoot":"","sources":["../../src/parse/vitest.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAezD,MAAM,UAAU,+BAA+B,CAC7C,MAAwB,EACxB,YAAiC,EACjC,IAAa;IAEb,MAAM,OAAO,GAA0B,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,uBAAuB,EAAE,IAAI,CAAC,CAAC;QAC7E,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,IAAI,EAAE,CAAC;QAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC;gBACX,YAAY;gBACZ,KAAK,EAAE,IAAI;gBACX,MAAM,EAAE,QAAQ;gBAChB,OAAO;gBACP,MAAM,EAAE,IAAI;gBACZ,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACjE,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;YAChC,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,QAAQ;gBAAE,SAAS;YACzD,MAAM,KAAK,GACT,gBAAgB,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,gBAAgB,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;YACxF,OAAO,CAAC,IAAI,CAAC;gBACX,YAAY;gBACZ,KAAK;gBACL,MAAM;gBACN,OAAO;aACR,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}