spec-controller 0.1.0-alpha.4 → 0.1.0-alpha.40

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 (114) hide show
  1. package/README.md +34 -6
  2. package/dist/cli-allocate/cli.d.ts +2 -0
  3. package/dist/cli-allocate/cli.d.ts.map +1 -0
  4. package/dist/cli-allocate/cli.js +57 -0
  5. package/dist/cli-allocate/cli.js.map +1 -0
  6. package/dist/cli-allocate/readHistory.d.ts +29 -0
  7. package/dist/cli-allocate/readHistory.d.ts.map +1 -0
  8. package/dist/cli-allocate/readHistory.js +136 -0
  9. package/dist/cli-allocate/readHistory.js.map +1 -0
  10. package/dist/cli-allocate/readParts.d.ts +3 -0
  11. package/dist/cli-allocate/readParts.d.ts.map +1 -0
  12. package/dist/cli-allocate/readParts.js +28 -0
  13. package/dist/cli-allocate/readParts.js.map +1 -0
  14. package/dist/cli-allocate/readTree.d.ts +16 -0
  15. package/dist/cli-allocate/readTree.d.ts.map +1 -0
  16. package/dist/cli-allocate/readTree.js +106 -0
  17. package/dist/cli-allocate/readTree.js.map +1 -0
  18. package/dist/cli-allocate/refStore.d.ts +3 -0
  19. package/dist/cli-allocate/refStore.d.ts.map +1 -0
  20. package/dist/cli-allocate/refStore.js +47 -0
  21. package/dist/cli-allocate/refStore.js.map +1 -0
  22. package/dist/cli-allocate/request.d.ts +11 -0
  23. package/dist/cli-allocate/request.d.ts.map +1 -0
  24. package/dist/cli-allocate/request.js +29 -0
  25. package/dist/cli-allocate/request.js.map +1 -0
  26. package/dist/cli-allocate/stderr.d.ts +14 -0
  27. package/dist/cli-allocate/stderr.d.ts.map +1 -0
  28. package/dist/cli-allocate/stderr.js +33 -0
  29. package/dist/cli-allocate/stderr.js.map +1 -0
  30. package/dist/cli-allocate/unreadable.d.ts +24 -0
  31. package/dist/cli-allocate/unreadable.d.ts.map +1 -0
  32. package/dist/cli-allocate/unreadable.js +43 -0
  33. package/dist/cli-allocate/unreadable.js.map +1 -0
  34. package/dist/cli-args.d.ts +73 -18
  35. package/dist/cli-args.d.ts.map +1 -1
  36. package/dist/cli-args.js +244 -22
  37. package/dist/cli-args.js.map +1 -1
  38. package/dist/cli-balance/cli.d.ts +31 -13
  39. package/dist/cli-balance/cli.d.ts.map +1 -1
  40. package/dist/cli-balance/cli.js +205 -251
  41. package/dist/cli-balance/cli.js.map +1 -1
  42. package/dist/cli-balance/emit/writer.d.ts +8 -23
  43. package/dist/cli-balance/emit/writer.d.ts.map +1 -1
  44. package/dist/cli-balance/emit/writer.js +24 -32
  45. package/dist/cli-balance/emit/writer.js.map +1 -1
  46. package/dist/cli-balance/exitStatus.d.ts +3 -0
  47. package/dist/cli-balance/exitStatus.d.ts.map +1 -0
  48. package/dist/cli-balance/exitStatus.js +12 -0
  49. package/dist/cli-balance/exitStatus.js.map +1 -0
  50. package/dist/cli-balance/reRender.d.ts +22 -0
  51. package/dist/cli-balance/reRender.d.ts.map +1 -0
  52. package/dist/cli-balance/reRender.js +36 -0
  53. package/dist/cli-balance/reRender.js.map +1 -0
  54. package/dist/cli-balance/unreadableInputs.d.ts +35 -0
  55. package/dist/cli-balance/unreadableInputs.d.ts.map +1 -0
  56. package/dist/cli-balance/unreadableInputs.js +101 -0
  57. package/dist/cli-balance/unreadableInputs.js.map +1 -0
  58. package/dist/cli-registry.d.ts +28 -0
  59. package/dist/cli-registry.d.ts.map +1 -1
  60. package/dist/cli-registry.js +40 -35
  61. package/dist/cli-registry.js.map +1 -1
  62. package/dist/cli.d.ts +4 -5
  63. package/dist/cli.d.ts.map +1 -1
  64. package/dist/cli.js +37 -21
  65. package/dist/cli.js.map +1 -1
  66. package/dist/host.d.ts +28 -3
  67. package/dist/host.d.ts.map +1 -1
  68. package/dist/host.js +137 -17
  69. package/dist/host.js.map +1 -1
  70. package/dist/ingest/gherkinValidation.d.ts +3 -7
  71. package/dist/ingest/gherkinValidation.d.ts.map +1 -1
  72. package/dist/ingest/gherkinValidation.js +3 -7
  73. package/dist/ingest/gherkinValidation.js.map +1 -1
  74. package/dist/ingest/ingestQualityChecks.d.ts +25 -54
  75. package/dist/ingest/ingestQualityChecks.d.ts.map +1 -1
  76. package/dist/ingest/ingestQualityChecks.js +112 -145
  77. package/dist/ingest/ingestQualityChecks.js.map +1 -1
  78. package/dist/ingest/ingestScenarios.d.ts +11 -17
  79. package/dist/ingest/ingestScenarios.d.ts.map +1 -1
  80. package/dist/ingest/ingestScenarios.js +52 -62
  81. package/dist/ingest/ingestScenarios.js.map +1 -1
  82. package/dist/ingest/inputShapes.d.ts +47 -0
  83. package/dist/ingest/inputShapes.d.ts.map +1 -0
  84. package/dist/ingest/inputShapes.js +143 -0
  85. package/dist/ingest/inputShapes.js.map +1 -0
  86. package/dist/outputLocation.d.ts +15 -0
  87. package/dist/outputLocation.d.ts.map +1 -0
  88. package/dist/outputLocation.js +39 -0
  89. package/dist/outputLocation.js.map +1 -0
  90. package/dist/run-management/keptRun.d.ts +27 -25
  91. package/dist/run-management/keptRun.d.ts.map +1 -1
  92. package/dist/run-management/keptRun.js +20 -21
  93. package/dist/run-management/keptRun.js.map +1 -1
  94. package/dist/storedRun.d.ts +27 -0
  95. package/dist/storedRun.d.ts.map +1 -0
  96. package/dist/storedRun.js +49 -0
  97. package/dist/storedRun.js.map +1 -0
  98. package/package.json +2 -2
  99. package/dist/corpus/cli.d.ts +0 -34
  100. package/dist/corpus/cli.d.ts.map +0 -1
  101. package/dist/corpus/cli.js +0 -128
  102. package/dist/corpus/cli.js.map +0 -1
  103. package/dist/mutation-ratchet/index.d.ts +0 -51
  104. package/dist/mutation-ratchet/index.d.ts.map +0 -1
  105. package/dist/mutation-ratchet/index.js +0 -51
  106. package/dist/mutation-ratchet/index.js.map +0 -1
  107. package/dist/mutation-ratchet/record.d.ts +0 -178
  108. package/dist/mutation-ratchet/record.d.ts.map +0 -1
  109. package/dist/mutation-ratchet/record.js +0 -314
  110. package/dist/mutation-ratchet/record.js.map +0 -1
  111. package/dist/mutation-ratchet/report.d.ts +0 -109
  112. package/dist/mutation-ratchet/report.d.ts.map +0 -1
  113. package/dist/mutation-ratchet/report.js +0 -156
  114. package/dist/mutation-ratchet/report.js.map +0 -1
@@ -15,30 +15,11 @@
15
15
  import { type GherkinParseError } from "./gherkinValidation.js";
16
16
  import { type EvidenceObligations } from "@3f-consulting/spec-controller-core";
17
17
  import type { EvidenceReconciliation } from "@3f-consulting/spec-controller-core";
18
- /**
19
- * A reader over ONE resolution pass's records.
20
- *
21
- * EACH RECORD IS OPENED ONCE, WHICH IS WHY THIS IS A CLOSURE AND NOT A FUNCTION PER REFERENCE. A
22
- * manifest may name several gates of one record, and a reader opening it per entry would let two
23
- * references answer for two different states of the same file — a rewrite landing mid-pass, a gate
24
- * present for one and gone for the next. One read makes the pass's bars one reading of one record.
25
- *
26
- * THE REFUSAL IS REMEMBERED TOO. Cacheing only the successes would re-open an absent or unreadable
27
- * record per reference, which is the same disagreement by the other door — and the likelier door,
28
- * since a record being rewritten is unreadable for exactly the window that matters.
29
- *
30
- * THE SUBTRACTION IS THE RECORD'S, NOT THIS EDGE'S. `killFloorOf` spends the allowance; an edge
31
- * computing `detected - slack` itself would be a second place holding a fact about the record.
32
- */
33
- export declare function killFloorReaderFor(root: string): (reference: {
34
- readonly mutationGate: string;
35
- readonly recordFile?: string;
36
- }) => number | null;
37
18
  /**
38
19
  * The reconciler's resolved input paths — the CLI options threaded to the readers.
39
20
  * Every path is optional; a missing result file is tolerated (its evidence is
40
21
  * simply absent). `packageJson` is the EXTERNALLY-SPECIFIED package.json the static
41
- * static-check reader reads `exists` from (the --package-json seam, @SCN-LNT-005):
22
+ * static-check reader reads `exists` from (the --package-json seam):
42
23
  * default the tool's own cwd `package.json`; set it to reconcile ANOTHER repo's
43
24
  * static checks — required to render the historical watermelon correctly.
44
25
  */
@@ -49,13 +30,7 @@ export interface ReconcileOptions {
49
30
  ci?: string;
50
31
  packageJson?: string;
51
32
  /**
52
- * The measurement artefact (@SCN-CIP-003) — the number each measured check posted, and
53
- * the credit side of every measured fitness check. Optional like the other result files: absent,
54
- * it contributes nothing, and each measured obligation it would have answered reads `missing`.
55
- */
56
- measurements?: string;
57
- /**
58
- * The CI RUN'S OWN RECORD of what each of its steps did (@SCN-LNT-021, @SCN-LNT-028) — the credit
33
+ * The CI RUN'S OWN RECORD of what each of its steps did — the credit
59
34
  * side of every CONVERTED fitness check, written by the consumer's own pipeline and by neither
60
35
  * party to this reconciliation.
61
36
  *
@@ -68,8 +43,12 @@ export interface ReconcileOptions {
68
43
  */
69
44
  ciSteps?: string;
70
45
  }
46
+ /** Where the CI workflows are read from when `--ci` is not given. */
47
+ export declare const DEFAULT_CI_PATH = ".github/workflows";
48
+ /** The target's manifest when `--package-json` is not given: the one in the directory the run is in. */
49
+ export declare const DEFAULT_PACKAGE_JSON = "package.json";
71
50
  /**
72
- * The feature corpus's INTEGRITY CHECKPOINT (@SCN-CLI-016, 3F-1767) — validate every discovered
51
+ * The feature corpus's INTEGRITY CHECKPOINT — validate every discovered
73
52
  * `.feature` with the REAL Gherkin parser and report the files it cannot read.
74
53
  *
75
54
  * The feature corpus is the ledger's DEBIT side, and it used to be read by a tag-line scan that
@@ -77,7 +56,7 @@ export interface ReconcileOptions {
77
56
  * spec could read BALANCED. A file the parser rejects is one cucumber would refuse to run: the
78
57
  * CLI halts on it (exit 2) rather than reconciling a corpus that is a fiction.
79
58
  *
80
- * THIS IS NOW THE CATCH SITE, NOT THE CALL SITE (@SCN-GPG-001, 3F-2817). The validation moved
59
+ * THIS IS NOW THE CATCH SITE, NOT THE CALL SITE. The validation moved
81
60
  * into `discoverFeatures`, which REFUSES an unreadable corpus rather than returning one, so every
82
61
  * corpus reader inherits the refusal instead of each restating it. What is left here is the
83
62
  * translation back into the list this CLI edge already prints — same files, same order, same
@@ -85,38 +64,30 @@ export interface ReconcileOptions {
85
64
  * refusal is not ours to interpret and rethrows.
86
65
  */
87
66
  export declare function featureCorpusParseErrors(featuresDir: string | undefined): GherkinParseError[];
67
+ /** A read of the feature corpus or the CI workflows that the operating system refused. */
68
+ export interface InputReadFault {
69
+ readonly path: string;
70
+ readonly reason: string;
71
+ }
88
72
  /**
89
- * The `@SCN` ids the feature corpus CARRIES MORE THAN ONCE (@SCN-LDG-020's guardrail, 3F-1775).
90
- *
91
- * An `@SCN` identifies exactly ONE scenario — that is the whole basis of attributing evidence to
92
- * it. If two scenarios carry the same id, a test citing it could be proving EITHER, and the tool
93
- * cannot know which: the corpus is ambiguous, and any verdict over it is a guess.
94
- *
95
- * WHY THIS EXISTS. Tag inheritance made this reachable: an `@SCN` hoisted to a `Feature:`/`Rule:`
96
- * is inherited by every scenario beneath it (cucumber does this, so we do — parity). Left
97
- * unhandled, ONE passing test then marked EVERY scenario sharing that id `balanced`, including
98
- * scenarios nothing proves — a BALANCED-WHEN-BROKEN run, exit 0. A new silent false-green,
99
- * introduced by the very fix that closed the last one.
100
- *
101
- * Refused at the edge (exit 2) rather than reconciled, under the Rule already shipped for the
102
- * observed side and the corrupt corpus (@SCN-CLI-014/015/016): an input the tool cannot read is a
103
- * usage error, never a verdict. Whether hoisting an `@SCN` is an authoring fault worth a richer
104
- * diagnostic is the deferred policy question (3F-1774's sibling); refusing to reconcile a corpus we
105
- * cannot read is not a policy — it is the floor.
73
+ * The read of the feature corpus that failed, taken by the same discovery the reconcile uses, or
74
+ * null when it reads. A file the Gherkin parser rejects is not this fault: it is reported by
75
+ * `featureCorpusParseErrors`, after this.
106
76
  */
107
- export declare function featureCorpusDuplicateScnIds(featuresDir: string | undefined): string[];
77
+ export declare function corpusReadFault(featuresDir: string | undefined): InputReadFault | null;
78
+ /** The read of a CI workflow that failed, over the same files the reconcile reads, or null when they all read. */
79
+ export declare function ciReadFault(ciPath: string | undefined): InputReadFault | null;
108
80
  /**
109
81
  * Read the target's `feature-code → slug` map over the same `discoverFeatures` corpus
110
- * (@SCN-RPT-006) — each coded feature file's `@<FFF>` header (`featureCode`)
82
+ * — each coded feature file's `@<FFF>` header (`featureCode`)
111
83
  * mapped to its filename `slug`, the full feature name. This is the mapping
112
84
  * `scenariosFromFeatures` discards (it keeps only the parsed scenarios). A sibling read to
113
85
  * the balance, threaded to `renderMarkdown` (via `writeOutputs`) as the 5th sibling arg
114
86
  * (markdown-only — the by-feature cut is markdown-only, so it is NOT serialised to JSON).
115
87
  * Uncoded files (`featureCode === null`) are omitted, so the by-feature emitter falls
116
- * back to the bare `FFF` for any id whose code no file registers. One-prefix-one-file holds
117
- * by invariant (`corpusFaults` raises `duplicate-feature-code`, @SCN-STG-010), so the map is
118
- * unambiguous. That invariant was `lintFeatureCodes`' until 3F-3313; it is the shipped command's
119
- * now, which is the first time a CONSUMER of this reader has it too.
88
+ * back to the bare `FFF` for any id whose code no file registers. When two files carry one
89
+ * code the map keeps the last, and that run lists `duplicate-feature-code` under Scenario code
90
+ * errors and fails, so a report whose map is ambiguous never passes.
120
91
  */
121
92
  export declare function readFeatureNames(featuresDir?: string): Map<string, string>;
122
93
  /**
@@ -124,8 +95,8 @@ export declare function readFeatureNames(featuresDir?: string): Map<string, stri
124
95
  * `discoverFeatures` corpus `scenariosFromFeatures` reads): sum the raw @SCN
125
96
  * occurrences (`countScnOccurrences`) and the scenario count
126
97
  * (`parseScenarios(...).length`) across every file, and build the `EvidenceObligations`
127
- * sibling (@SCN-RPT-008). Also collects the UNTAGGED scenarios
128
- * (@SCN-RPT-014) — `parseUntaggedScenarios` per file, each paired with its feature-file
98
+ * sibling. Also collects the UNTAGGED scenarios
99
+ * — `parseUntaggedScenarios` per file, each paired with its feature-file
129
100
  * locator, sorted by (feature, scenario). Read alongside the balance in `main()` and
130
101
  * threaded to the renderers via `writeOutputs`; `runReconcile` stays unchanged.
131
102
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ingestQualityChecks.d.ts","sourceRoot":"","sources":["../../src/ingest/ingestQualityChecks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAYH,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,qCAAqC,CAAC;AA+B7C,OAAO,KAAK,EAIV,sBAAsB,EACvB,MAAM,qCAAqC,CAAC;AAwD7C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,GAMX,CAAC,SAAS,EAAE;IAAE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,MAAM,GAAG,IAAI,CAc/F;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA8ED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,iBAAiB,EAAE,CAQ7F;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAStF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAM1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAqB9E;AA2CD,wBAAgB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,sBAAsB,CAgE3E"}
1
+ {"version":3,"file":"ingestQualityChecks.d.ts","sourceRoot":"","sources":["../../src/ingest/ingestQualityChecks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAaH,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,qCAAqC,CAAC;AAkB7C,OAAO,KAAK,EAIV,sBAAsB,EACvB,MAAM,qCAAqC,CAAC;AA4B7C;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qEAAqE;AACrE,eAAO,MAAM,eAAe,sBAAsB,CAAC;AAEnD,wGAAwG;AACxG,eAAO,MAAM,oBAAoB,iBAAiB,CAAC;AA8EnD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,iBAAiB,EAAE,CAQ7F;AAED,0FAA0F;AAC1F,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAaD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,GAAG,IAAI,CAUtF;AAED,kHAAkH;AAClH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,GAAG,IAAI,CAU7E;AAaD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAM1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAuB9E;AAyCD,wBAAgB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,sBAAsB,CAoE3E"}
@@ -13,29 +13,23 @@
13
13
  * `package.json` to observe each fitness check the corpus cites.
14
14
  */
15
15
  import { readFileSync, existsSync } from "node:fs";
16
- import { basename, join } from "node:path";
16
+ import { basename } from "node:path";
17
17
  import { ciSourcePathsOf } from "./ciSourcePaths.js";
18
18
  import { discoverFeatures } from "./ingestScenarios.js";
19
- import { parseScenarios, countScnOccurrences, parseUntaggedScenarios, proseOnlyCodes, } from "@3f-consulting/spec-controller-core";
19
+ import { parseScenarios, countScnOccurrences, parseUntaggedScenarios, proseOnlyCodes, sharedScnCodesOf, } from "@3f-consulting/spec-controller-core";
20
20
  import { MissingFeatureCorpusError, UnreadableFeatureCorpusError, } from "./gherkinValidation.js";
21
21
  import { DEFAULT_DEFERRAL_TAGS } from "../deferralTags.js";
22
22
  import { evidenceObligations, } from "@3f-consulting/spec-controller-core";
23
23
  import { parseVitestEvidenceObservations, } from "@3f-consulting/spec-controller-core";
24
24
  import { parseCucumberEvidenceObservations, } from "@3f-consulting/spec-controller-core";
25
- // THE WHOLE COMPOSITION, THROUGH THE PUBLIC BARREL AND NOTHING ELSE (3F-3086). This module travels
26
- // in the tarball, and until 3F-3089 it reached nine core symbols through the UNPUBLISHED
25
+ // THE WHOLE COMPOSITION, THROUGH THE PUBLIC BARREL AND NOTHING ELSE. This module travels
26
+ // in the tarball, and it once reached nine core symbols through the UNPUBLISHED
27
27
  // `./internal` subpath to assemble the reconciliation itself — which is why an installed
28
28
  // `spec-controller balance --help` threw ERR_PACKAGE_PATH_NOT_EXPORTED while every gate in this
29
- // workspace stayed green. The nine are still internal (3F-2837 stands, unamended); what moved is
29
+ // workspace stayed green. The nine are still internal; what moved is
30
30
  // their CALLER. What is left here is the reads: this edge opens the files and hands the bytes over.
31
31
  import { evidenceReconciliationFromSources } from "@3f-consulting/spec-controller-core";
32
32
  import { resolveTargetRoot } from "../run-management/resolveRunInputs.js";
33
- // The record reader, reached for the RECORD half of a bar that names a gate (@SCN-MUT-012): its
34
- // conventional record name, its parser, and the floor a gate's own figures imply. Through the
35
- // barrel, which is the surface a caller holds. (The directory is still spelled `mutation-ratchet`
36
- // and the ratchet it was named for is deleted — 3F-3337 left the name standing rather than move a
37
- // module inside a delete; filed as a finding.)
38
- import { gateRecordFor, killFloorOf, MalformedRecordError, parseGateRecords, RECORD_FILE, } from "../mutation-ratchet/index.js";
39
33
  /**
40
34
  * The per-input FALLBACK quality-check for each JS-ecosystem result source — the
41
35
  * source→quality-check mapping, SET at the CLI edge rather than hardcoded in the core
@@ -46,7 +40,7 @@ import { gateRecordFor, killFloorOf, MalformedRecordError, parseGateRecords, REC
46
40
  const VITEST_QUALITY_CHECK = "unit";
47
41
  const CUCUMBER_QUALITY_CHECK = "integration";
48
42
  /**
49
- * THIS TOOL, RUN TO RECONCILE (@SCN-USG-014, 3F-3343) — the invocation whose step is the
43
+ * THIS TOOL, RUN TO RECONCILE — the invocation whose step is the
50
44
  * reconciler rather than one of the reconciled rows, SET at the CLI edge and injected into the
51
45
  * core like the prefixes above and the workflow names below.
52
46
  *
@@ -54,74 +48,16 @@ const CUCUMBER_QUALITY_CHECK = "integration";
54
48
  * publishes and `balance` is the command that reconciles; the engine holds neither, and a core
55
49
  * that assumed them would be asserting something about a command line it never sees.
56
50
  *
57
- * BOTH TOKENS, AND THE SECOND IS NOT DECORATION. This repository's own pipeline runs
58
- * `pnpm spec-controller tags` beside its balance step — the same binary, doing something that is
59
- * an ordinary step of the pipeline being reconciled — so an invocation naming the binary alone
60
- * would take that step off the books. The comparison is whole, adjacent shell tokens
51
+ * BOTH TOKENS, AND THE SECOND IS NOT DECORATION. A step running the same binary for anything but
52
+ * `balance` is an ordinary step of the pipeline being reconciled, so an invocation naming the
53
+ * binary alone would take that step off the books. The comparison is whole, adjacent shell tokens
61
54
  * (`parse/commandRuns`), so this names the reconciliation and nothing else the tool can do.
62
55
  */
63
56
  const RECONCILER_INVOCATION = "spec-controller balance";
64
- /**
65
- * A refusal met with an absent bar rather than let out of this edge.
66
- *
67
- * NOTHING IS THROWN OUT OF HERE, and that is the stance rather than caution. A refusal that escapes
68
- * costs the whole run its verdict over one bad character in a file nobody may even be reading — a
69
- * fault that is loud nowhere, where an absent bar is loud on the ledger. It is `thresholdsOf`'s own
70
- * stance for a malformed entry, applied to the half of a bar that now lives in a second file.
71
- *
72
- * TWO CLASSES AND NO MORE. The record library normalises every fault it can see — the YAML parser's
73
- * own included — into `MalformedRecordError` precisely so a caller catches all of them by catching
74
- * one; beside it sits the read that never got as far as a record. A bare catch would swallow a
75
- * defect in this edge as well, and answer it with the same silent absence.
76
- */
77
- function orNoBar(read) {
78
- try {
79
- return read();
80
- }
81
- catch (cause) {
82
- if (cause instanceof MalformedRecordError || isReadRefusal(cause))
83
- return null;
84
- throw cause;
85
- }
86
- }
87
- /** A filesystem refusal — the record was not there, or could not be opened. */
88
- function isReadRefusal(cause) {
89
- return cause instanceof Error && typeof cause.code === "string";
90
- }
91
- /**
92
- * A reader over ONE resolution pass's records.
93
- *
94
- * EACH RECORD IS OPENED ONCE, WHICH IS WHY THIS IS A CLOSURE AND NOT A FUNCTION PER REFERENCE. A
95
- * manifest may name several gates of one record, and a reader opening it per entry would let two
96
- * references answer for two different states of the same file — a rewrite landing mid-pass, a gate
97
- * present for one and gone for the next. One read makes the pass's bars one reading of one record.
98
- *
99
- * THE REFUSAL IS REMEMBERED TOO. Cacheing only the successes would re-open an absent or unreadable
100
- * record per reference, which is the same disagreement by the other door — and the likelier door,
101
- * since a record being rewritten is unreadable for exactly the window that matters.
102
- *
103
- * THE SUBTRACTION IS THE RECORD'S, NOT THIS EDGE'S. `killFloorOf` spends the allowance; an edge
104
- * computing `detected - slack` itself would be a second place holding a fact about the record.
105
- */
106
- export function killFloorReaderFor(root
107
- // The reader's shape is SPELLED here rather than imported, and that is the boundary working
108
- // rather than a duplication. `KillFloorReader` and the reference it takes are core-internal —
109
- // the registry-home question (increment D) still governs them — and this module is published, so
110
- // naming them by their `./internal` types would put an unpublished specifier back in the tarball
111
- // for a type alone. Structural typing is what makes the closure the engine's parameter accepts.
112
- ) {
113
- const opened = new Map();
114
- return (reference) => {
115
- const recordFile = reference.recordFile ?? RECORD_FILE;
116
- if (!opened.has(recordFile)) {
117
- opened.set(recordFile, orNoBar(() => parseGateRecords(readFileSync(join(root, recordFile), "utf8"), recordFile)));
118
- }
119
- const records = opened.get(recordFile);
120
- if (records == null)
121
- return null;
122
- return orNoBar(() => killFloorOf(gateRecordFor(reference.mutationGate, records, recordFile)));
123
- };
124
- }
57
+ /** Where the CI workflows are read from when `--ci` is not given. */
58
+ export const DEFAULT_CI_PATH = ".github/workflows";
59
+ /** The target's manifest when `--package-json` is not given: the one in the directory the run is in. */
60
+ export const DEFAULT_PACKAGE_JSON = "package.json";
125
61
  /** Read + JSON-parse a file if present, else return undefined. */
126
62
  function readJsonIfPresent(path) {
127
63
  if (!path || !existsSync(path))
@@ -129,27 +65,27 @@ function readJsonIfPresent(path) {
129
65
  return JSON.parse(readFileSync(path, "utf8"));
130
66
  }
131
67
  /**
132
- * THE CORPUS `balance` READS — the shared discovery, with an ABSENT directory read as NO CORPUS
133
- * (@SCN-CLI-017, 3F-3345). The single place this command opts in.
68
+ * THE CORPUS `balance` READS — the shared discovery, with an ABSENT directory read as NO CORPUS.
69
+ * The single place this command opts in.
134
70
  *
135
71
  * `new-client` is a supported adoption state, not a degraded one, and most targets have no
136
72
  * `features/` directory at all — so an absent DEFAULT corpus is the target's honest shape and
137
73
  * `balance` reports on it. Left to escape it was a raw `ENOENT` landing on Node's default exit 1,
138
- * the OUT-OF-BALANCE code, which is exactly the collision @SCN-CLI-014/015/016 closed on every
74
+ * the OUT-OF-BALANCE code, which is exactly the collision the unreadable-input guards closed on every
139
75
  * other input, alive on the one path each new consumer is guaranteed to take.
140
76
  *
141
77
  * ONE HELPER, NOT FIVE CATCHES, and that is the whole reason it exists: five readers each doing
142
78
  * this by hand is five chances for one to stay intolerant, and a run that reports on a corpus for
143
79
  * four of its readings and throws on the fifth is worse than one that throws. The translation is
144
80
  * also why `discoverFeatures` is not the place to be tolerant — see its own note, and
145
- * `MissingFeatureCorpusError`'s: `tags` reaches the same reader and keeps refusing.
81
+ * `MissingFeatureCorpusError`'s.
146
82
  *
147
- * IT IS `[]`, NOT A VERDICT. Zero rows is what @SCN-CLI-019 reads as NOTHING TO RECONCILE, and a
83
+ * IT IS `[]`, NOT A VERDICT. Zero rows is what the verdict reads as NOTHING TO RECONCILE, and a
148
84
  * corpus-less target that still has uncited credits keeps its suspense row and its exit 1
149
- * (@SCN-CLI-020) — this reader says what it found, never what the run means.
85
+ * — this reader says what it found, never what the run means.
150
86
  *
151
87
  * A supplied-but-absent `--features` never arrives here: `checkInputsExist` refuses it at the CLI
152
- * edge, exit 2 (@SCN-CLI-002). The precedent is `ciSourcePathsOf`, which already answers an absent
88
+ * edge, exit 2. The precedent is `ciSourcePathsOf`, which already answers an absent
153
89
  * DEFAULT `.github/workflows` with `[]` for the same reason — the default finding nothing is a fact
154
90
  * about the target, not a mistake by its author.
155
91
  */
@@ -167,7 +103,7 @@ function balanceCorpus(featuresDir) {
167
103
  * The discovered feature corpus's SOURCES — read once so the two readings a citing run needs (the
168
104
  * obligations, and the corpus hop's `check tag → @SCN`) are taken from the same bytes. Two
169
105
  * discoveries could disagree about the corpus, and a citation resolved against a corpus the ledger
170
- * was not built from is exactly the phantom-row fault (@SCN-LNT-009).
106
+ * was not built from is exactly the phantom-row fault.
171
107
  */
172
108
  function featureSources(featuresDir) {
173
109
  return balanceCorpus(featuresDir).map((f) => readFileSync(f.path, "utf8"));
@@ -176,7 +112,7 @@ function scenariosFromFeatures(featuresDir, deferralTags = DEFAULT_DEFERRAL_TAGS
176
112
  return featureSources(featuresDir).flatMap((source) => parseScenarios(source, deferralTags));
177
113
  }
178
114
  /**
179
- * The feature corpus's UNTAGGED half (@SCN-LDG-021, 3F-1774) — the scenarios `parseScenarios`
115
+ * The feature corpus's UNTAGGED half — the scenarios `parseScenarios`
180
116
  * discards because they carry no `@SCN`. They are REAL scenarios: cucumber runs them, so each
181
117
  * owns a real Evidence Obligation — but the obligation has no code for an Evidence Observation to
182
118
  * link to, so it can never be discharged. `reconcile` gives each its own out-of-balance row
@@ -191,7 +127,7 @@ function untaggedScenariosFromFeatures(featuresDir) {
191
127
  return balanceCorpus(featuresDir).flatMap((f) => parseUntaggedScenarios(readFileSync(f.path, "utf8")).map((scenario) => `${f.slug}.feature : ${scenario}`));
192
128
  }
193
129
  /**
194
- * The feature corpus's INTEGRITY CHECKPOINT (@SCN-CLI-016, 3F-1767) — validate every discovered
130
+ * The feature corpus's INTEGRITY CHECKPOINT — validate every discovered
195
131
  * `.feature` with the REAL Gherkin parser and report the files it cannot read.
196
132
  *
197
133
  * The feature corpus is the ledger's DEBIT side, and it used to be read by a tag-line scan that
@@ -199,7 +135,7 @@ function untaggedScenariosFromFeatures(featuresDir) {
199
135
  * spec could read BALANCED. A file the parser rejects is one cucumber would refuse to run: the
200
136
  * CLI halts on it (exit 2) rather than reconciling a corpus that is a fiction.
201
137
  *
202
- * THIS IS NOW THE CATCH SITE, NOT THE CALL SITE (@SCN-GPG-001, 3F-2817). The validation moved
138
+ * THIS IS NOW THE CATCH SITE, NOT THE CALL SITE. The validation moved
203
139
  * into `discoverFeatures`, which REFUSES an unreadable corpus rather than returning one, so every
204
140
  * corpus reader inherits the refusal instead of each restating it. What is left here is the
205
141
  * translation back into the list this CLI edge already prints — same files, same order, same
@@ -218,46 +154,72 @@ export function featureCorpusParseErrors(featuresDir) {
218
154
  }
219
155
  }
220
156
  /**
221
- * The `@SCN` ids the feature corpus CARRIES MORE THAN ONCE (@SCN-LDG-020's guardrail, 3F-1775).
222
- *
223
- * An `@SCN` identifies exactly ONE scenario — that is the whole basis of attributing evidence to
224
- * it. If two scenarios carry the same id, a test citing it could be proving EITHER, and the tool
225
- * cannot know which: the corpus is ambiguous, and any verdict over it is a guess.
226
- *
227
- * WHY THIS EXISTS. Tag inheritance made this reachable: an `@SCN` hoisted to a `Feature:`/`Rule:`
228
- * is inherited by every scenario beneath it (cucumber does this, so we do — parity). Left
229
- * unhandled, ONE passing test then marked EVERY scenario sharing that id `balanced`, including
230
- * scenarios nothing proves — a BALANCED-WHEN-BROKEN run, exit 0. A new silent false-green,
231
- * introduced by the very fix that closed the last one.
232
- *
233
- * Refused at the edge (exit 2) rather than reconciled, under the Rule already shipped for the
234
- * observed side and the corrupt corpus (@SCN-CLI-014/015/016): an input the tool cannot read is a
235
- * usage error, never a verdict. Whether hoisting an `@SCN` is an authoring fault worth a richer
236
- * diagnostic is the deferred policy question (3F-1774's sibling); refusing to reconcile a corpus we
237
- * cannot read is not a policy — it is the floor.
157
+ * A read the operating system refused, as a fault naming the path; null for anything else. Every
158
+ * refusal is the same fault to the run, whichever it is: a file where a directory is read or the
159
+ * reverse, a path it is not permitted to read, or any other reason the OS gives.
238
160
  */
239
- export function featureCorpusDuplicateScnIds(featuresDir) {
240
- const seen = new Set();
241
- const duplicates = new Set();
242
- for (const scenario of scenariosFromFeatures(featuresDir)) {
243
- if (seen.has(scenario.scnId))
244
- duplicates.add(scenario.scnId);
245
- seen.add(scenario.scnId);
161
+ function readFaultOf(err, path) {
162
+ const errno = err;
163
+ if (!(err instanceof Error) || typeof errno.code !== "string")
164
+ return null;
165
+ return { path: errno.path ?? path, reason: err.message };
166
+ }
167
+ /**
168
+ * The read of the feature corpus that failed, taken by the same discovery the reconcile uses, or
169
+ * null when it reads. A file the Gherkin parser rejects is not this fault: it is reported by
170
+ * `featureCorpusParseErrors`, after this.
171
+ */
172
+ export function corpusReadFault(featuresDir) {
173
+ try {
174
+ balanceCorpus(featuresDir);
175
+ return null;
176
+ }
177
+ catch (err) {
178
+ if (err instanceof UnreadableFeatureCorpusError)
179
+ return null;
180
+ const fault = readFaultOf(err, featuresDir ?? "features");
181
+ if (fault === null)
182
+ throw err;
183
+ return fault;
184
+ }
185
+ }
186
+ /** The read of a CI workflow that failed, over the same files the reconcile reads, or null when they all read. */
187
+ export function ciReadFault(ciPath) {
188
+ const path = ciPath ?? DEFAULT_CI_PATH;
189
+ try {
190
+ for (const source of ciSourcePathsOf(path))
191
+ readCiSource(source);
192
+ return null;
193
+ }
194
+ catch (err) {
195
+ const fault = readFaultOf(err, path);
196
+ if (fault === null)
197
+ throw err;
198
+ return fault;
199
+ }
200
+ }
201
+ /** One workflow file's read, whose failure carries the file's path, which reading a directory gives none of. */
202
+ function readCiSource(source) {
203
+ try {
204
+ readFileSync(source, "utf8");
205
+ }
206
+ catch (err) {
207
+ const errno = err;
208
+ errno.path ??= source;
209
+ throw err;
246
210
  }
247
- return [...duplicates].sort();
248
211
  }
249
212
  /**
250
213
  * Read the target's `feature-code → slug` map over the same `discoverFeatures` corpus
251
- * (@SCN-RPT-006) — each coded feature file's `@<FFF>` header (`featureCode`)
214
+ * — each coded feature file's `@<FFF>` header (`featureCode`)
252
215
  * mapped to its filename `slug`, the full feature name. This is the mapping
253
216
  * `scenariosFromFeatures` discards (it keeps only the parsed scenarios). A sibling read to
254
217
  * the balance, threaded to `renderMarkdown` (via `writeOutputs`) as the 5th sibling arg
255
218
  * (markdown-only — the by-feature cut is markdown-only, so it is NOT serialised to JSON).
256
219
  * Uncoded files (`featureCode === null`) are omitted, so the by-feature emitter falls
257
- * back to the bare `FFF` for any id whose code no file registers. One-prefix-one-file holds
258
- * by invariant (`corpusFaults` raises `duplicate-feature-code`, @SCN-STG-010), so the map is
259
- * unambiguous. That invariant was `lintFeatureCodes`' until 3F-3313; it is the shipped command's
260
- * now, which is the first time a CONSUMER of this reader has it too.
220
+ * back to the bare `FFF` for any id whose code no file registers. When two files carry one
221
+ * code the map keeps the last, and that run lists `duplicate-feature-code` under Scenario code
222
+ * errors and fails, so a report whose map is ambiguous never passes.
261
223
  */
262
224
  export function readFeatureNames(featuresDir) {
263
225
  const map = new Map();
@@ -272,8 +234,8 @@ export function readFeatureNames(featuresDir) {
272
234
  * `discoverFeatures` corpus `scenariosFromFeatures` reads): sum the raw @SCN
273
235
  * occurrences (`countScnOccurrences`) and the scenario count
274
236
  * (`parseScenarios(...).length`) across every file, and build the `EvidenceObligations`
275
- * sibling (@SCN-RPT-008). Also collects the UNTAGGED scenarios
276
- * (@SCN-RPT-014) — `parseUntaggedScenarios` per file, each paired with its feature-file
237
+ * sibling. Also collects the UNTAGGED scenarios
238
+ * — `parseUntaggedScenarios` per file, each paired with its feature-file
277
239
  * locator, sorted by (feature, scenario). Read alongside the balance in `main()` and
278
240
  * threaded to the renderers via `writeOutputs`; `runReconcile` stays unchanged.
279
241
  */
@@ -283,9 +245,11 @@ export function readEvidenceObligations(features) {
283
245
  let scenarioCount = 0;
284
246
  const untagged = [];
285
247
  const sources = [];
248
+ const files = [];
286
249
  for (const f of featureFiles) {
287
250
  const source = readFileSync(f.path, "utf8");
288
251
  sources.push(source);
252
+ files.push({ feature: `${f.slug}.feature`, source });
289
253
  raw += countScnOccurrences(source);
290
254
  scenarioCount += parseScenarios(source).length;
291
255
  for (const scenario of parseUntaggedScenarios(source)) {
@@ -295,14 +259,14 @@ export function readEvidenceObligations(features) {
295
259
  untagged.sort((a, b) => a.feature.localeCompare(b.feature) || a.scenario.localeCompare(b.scenario));
296
260
  // The prose-only codes are a CROSS-CORPUS difference (a code tagged in any file isn't
297
261
  // dangling), so it reads all sources at once — not per-file like the others.
298
- return evidenceObligations(raw, scenarioCount, untagged, proseOnlyCodes(sources));
262
+ return evidenceObligations(raw, scenarioCount, untagged, proseOnlyCodes(sources), sharedScnCodesOf(files));
299
263
  }
300
264
  /**
301
265
  * Parse the target's RUNTIME observations ONCE — the tag-derived, per-tier observation set
302
- * (@SCN-RPT-017 / 3F-1452 FULL UNIFY) fed to BOTH the reconciler and the runtime census, so the
266
+ * fed to BOTH the reconciler and the runtime census, so the
303
267
  * two can never disagree. Each source's FALLBACK quality-check is set at the CLI edge
304
268
  * (vitest⇒unit, cucumber⇒integration); the parsers DERIVE the level from the cited scenario's tier
305
- * tag (@SCN-LDG-011 / 3F-1434), using the fallback only for an untagged scenario. A missing report
269
+ * tag, using the fallback only for an untagged scenario. A missing report
306
270
  * contributes nothing. Root-relative so a phantom-scenario row's where-to-fix stays portable.
307
271
  */
308
272
  function parseRuntimeObservations(opts, root) {
@@ -317,34 +281,41 @@ function parseRuntimeObservations(opts, root) {
317
281
  }
318
282
  export function runReconcile(opts) {
319
283
  // Read the target's package.json ONCE — its `specController.*` config supplies the deferral-tag
320
- // extension (@SCN-PND-021) and the configured fitness rows, and its `scripts` back the `exists`
284
+ // extension and the configured fitness rows, and its `scripts` back the `exists`
321
285
  // read. The disk read stays at this impure edge; the engine takes the resolved values as
322
286
  // injected params, staying pure.
323
- const pkgPath = opts.packageJson ?? "package.json";
287
+ const pkgPath = opts.packageJson ?? DEFAULT_PACKAGE_JSON;
324
288
  const packageJson = readJsonIfPresent(pkgPath) ?? {};
325
289
  // The TARGET repo root — the credit locators are made relative to it, so a phantom-scenario row's
326
- // where-to-fix (ruling Q5) stays portable in a banked artefact, and a bar naming a mutation gate
327
- // finds that target's record rather than this tool's own (@SCN-MUT-012). Resolved ONCE here and
328
- // threaded, which is also what keeps `execFileSync` and `process.cwd()` out of the engine.
290
+ // where-to-fix (ruling Q5) stays portable in a banked artefact. Resolved ONCE here and threaded,
291
+ // which is also what keeps `execFileSync` and `process.cwd()` out of the engine.
329
292
  const root = resolveTargetRoot({ features: opts.features });
330
293
  // `--ci` names a workflow FILE or a DIRECTORY of them, and defaults to the directory
331
- // (@SCN-USG-006, 3F-2238): a pipeline split across files enforces its checks just as one
294
+ // A pipeline split across files enforces its checks just as one
332
295
  // file does, and reading only ci.yml both invents watermelons for named checks enforced
333
296
  // elsewhere and drops uncited ones off the books entirely. Path semantics carry the
334
297
  // file-vs-directory distinction, so one flag stays one flag and an explicit file is still
335
- // a narrowing (@SCN-USG-008).
336
- const ciPath = opts.ci ?? ".github/workflows";
337
- // RESOLVED ONCE, READ TWICE (@SCN-USG-015). The engine takes anonymous source strings and holds
298
+ // a narrowing.
299
+ const ciPath = opts.ci ?? DEFAULT_CI_PATH;
300
+ // RESOLVED ONCE, READ TWICE. The engine takes anonymous source strings and holds
338
301
  // no filesystem, so the mapping from a step's source index back to the workflow file it came
339
302
  // from is made HERE, where the paths are already in hand — `ciSourcePaths.ts` is explicit that
340
303
  // keeping the core that way is the point. Resolving the list twice would be two chances for the
341
304
  // bytes and the names to fall out of the order they are paired by.
342
305
  const ciPaths = ciSourcePathsOf(ciPath);
306
+ // The corpus, discovered and read ONCE: its bytes, and — paired by index — which file each came
307
+ // from and the header code it carries, for the scenario code errors.
308
+ const corpusFiles = balanceCorpus(opts.features).map((f) => ({
309
+ slug: f.slug,
310
+ featureCode: f.featureCode,
311
+ source: readFileSync(f.path, "utf8"),
312
+ }));
343
313
  return evidenceReconciliationFromSources({
344
- // The corpus's bytes, read ONCE at this impure edge (3F-3088). The engine composes the three
314
+ // The corpus's bytes, read ONCE at this impure edge. The engine composes the three
345
315
  // readings a citing run needs from this one array, so they cannot be assembled from two
346
- // discoveries that disagree about the corpus (@SCN-LNT-009).
347
- featureSources: featureSources(opts.features),
316
+ // discoveries that disagree about the corpus.
317
+ featureSources: corpusFiles.map((f) => f.source),
318
+ featureFiles: corpusFiles.map(({ slug, featureCode }) => ({ slug, featureCode })),
348
319
  // The untagged half by its `<feature> : <scenario>` locator — parsed here because the locator
349
320
  // names the FILE, which the discovery knows and a source string does not.
350
321
  untaggedScenarios: untaggedScenariosFromFeatures(opts.features),
@@ -355,29 +326,25 @@ export function runReconcile(opts) {
355
326
  // half of the entry that does not come out of the workflow's own text. The directory it sits
356
327
  // in is the caller's `--ci`, not the consumer's subject, so it is not part of what they write.
357
328
  ciSourceNames: ciPaths.map((path) => basename(path)),
358
- measurements: readJsonIfPresent(opts.measurements) ?? {},
359
329
  // The CONVERTED checks' credit stream, read at this edge like every other report. Absent it is
360
- // undefined rather than empty, and that distinction reaches the reader (@SCN-LNT-027): "no
330
+ // undefined rather than empty, and that distinction reaches the reader: "no
361
331
  // record" is a run nobody recorded, "a record holding nothing" is a run that recorded none of
362
332
  // these steps, and those are opposite facts.
363
- // STRUCTURALLY, NOT BY NAME, for the reason `measurements` above is read that way: this module
364
- // travels in the tarball and reaches core through the PUBLIC barrel alone (3F-3086), and
333
+ // STRUCTURALLY, NOT BY NAME: this module travels in the tarball and reaches core through the PUBLIC barrel alone, and
365
334
  // `CiStepRecord` is not on it. The shape is the document's, which is the consumer's, so what is
366
335
  // written here is what the file holds rather than a contract owed to anyone.
367
336
  ciStepRecord: readJsonIfPresent(opts.ciSteps),
368
337
  runtimeObservations: parseRuntimeObservations(opts, root),
369
- // The three things the engine's resolvers cannot hold, and each for its own reason: the
370
- // starter deferral set is the application layer's own policy, how this tool is invoked to
371
- // reconcile is a fact about this product's command line, and the reader opens a file on the
372
- // target's tree. THE PREFIX SET USED TO SIT HERE AND IS GONE (@SCN-USG-004, 3F-3343): the
338
+ // The two things the engine's resolvers cannot hold, and each for its own reason: the
339
+ // starter deferral set is the application layer's own policy, and how this tool is invoked to
340
+ // reconcile is a fact about this product's command line. THE PREFIX SET USED TO SIT HERE AND IS GONE: the
373
341
  // engine no longer decides a check's membership by its name, so there is no convention left
374
342
  // for this edge to own.
375
343
  deferralTags: DEFAULT_DEFERRAL_TAGS,
376
344
  reconcilerInvocation: RECONCILER_INVOCATION,
377
- killFloor: killFloorReaderFor(root),
378
345
  });
379
346
  }
380
- // The static-check kind-counts are no longer read as a parallel census (@SCN-USG-001 / 3F-2118):
347
+ // The static-check kind-counts are no longer read as a parallel census:
381
348
  // the former `readStaticEvidenceObservationCounts` re-built the static check observations and
382
349
  // re-derived the running / uncited split from a second read of the CI config. That counting now
383
350
  // FOLDS onto the Ledger the reconciler already produced (`staticObservationTally`, an internal
@@ -1 +1 @@
1
- {"version":3,"file":"ingestQualityChecks.js","sourceRoot":"","sources":["../../src/ingest/ingestQualityChecks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ingestQualityChecks.js","sourceRoot":"","sources":["../../src/ingest/ingestQualityChecks.ts"],"names":[],"mappings":"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"}