@3f-consulting/spec-controller-core 0.1.0-alpha.7 → 0.1.0-alpha.71
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.
- package/README.md +3 -3
- package/dist/assemble/evidenceReconciliationFromSources.d.ts +5 -40
- package/dist/assemble/evidenceReconciliationFromSources.d.ts.map +1 -1
- package/dist/assemble/evidenceReconciliationFromSources.js +30 -325
- package/dist/assemble/evidenceReconciliationFromSources.js.map +1 -1
- package/dist/assemble/renderInput.d.ts +7 -73
- package/dist/assemble/renderInput.d.ts.map +1 -1
- package/dist/assemble/renderInput.js +3 -45
- package/dist/assemble/renderInput.js.map +1 -1
- package/dist/census/evidenceObligations.d.ts +11 -46
- package/dist/census/evidenceObligations.d.ts.map +1 -1
- package/dist/census/evidenceObligations.js +19 -25
- package/dist/census/evidenceObligations.js.map +1 -1
- package/dist/domain/evidenceOrder.d.ts +3 -0
- package/dist/domain/evidenceOrder.d.ts.map +1 -0
- package/dist/domain/evidenceOrder.js +15 -0
- package/dist/domain/evidenceOrder.js.map +1 -0
- package/dist/domain/evidenceReconciliation.d.ts +21 -391
- package/dist/domain/evidenceReconciliation.d.ts.map +1 -1
- package/dist/domain/evidenceReconciliation.js +87 -382
- package/dist/domain/evidenceReconciliation.js.map +1 -1
- package/dist/domain/featureCode.d.ts +4 -0
- package/dist/domain/featureCode.d.ts.map +1 -0
- package/dist/domain/featureCode.js +12 -0
- package/dist/domain/featureCode.js.map +1 -0
- package/dist/domain/journal.d.ts +8 -393
- package/dist/domain/journal.d.ts.map +1 -1
- package/dist/domain/journal.js +6 -118
- package/dist/domain/journal.js.map +1 -1
- package/dist/domain/ledger.d.ts +8 -328
- package/dist/domain/ledger.d.ts.map +1 -1
- package/dist/domain/ledger.js +23 -326
- package/dist/domain/ledger.js.map +1 -1
- package/dist/domain/messages.d.ts +213 -0
- package/dist/domain/messages.d.ts.map +1 -0
- package/dist/domain/messages.js +313 -0
- package/dist/domain/messages.js.map +1 -0
- package/dist/domain/outcome.d.ts +3 -0
- package/dist/domain/outcome.d.ts.map +1 -0
- package/dist/domain/outcome.js +2 -0
- package/dist/domain/outcome.js.map +1 -0
- package/dist/domain/posting.d.ts +8 -105
- package/dist/domain/posting.d.ts.map +1 -1
- package/dist/domain/posting.js +4 -56
- package/dist/domain/posting.js.map +1 -1
- package/dist/domain/qualityCheckFault.d.ts +3 -43
- package/dist/domain/qualityCheckFault.d.ts.map +1 -1
- package/dist/domain/qualityCheckFault.js +0 -24
- package/dist/domain/qualityCheckFault.js.map +1 -1
- package/dist/domain/qualityCheckReconciliation.d.ts +7 -280
- package/dist/domain/qualityCheckReconciliation.d.ts.map +1 -1
- package/dist/domain/qualityCheckReconciliation.js +63 -463
- package/dist/domain/qualityCheckReconciliation.js.map +1 -1
- package/dist/domain/qualityCheckReconciliationFault.d.ts +0 -19
- package/dist/domain/qualityCheckReconciliationFault.d.ts.map +1 -1
- package/dist/domain/qualityCheckReconciliationFault.js +1 -24
- package/dist/domain/qualityCheckReconciliationFault.js.map +1 -1
- package/dist/domain/scenarioCodeError.d.ts +16 -0
- package/dist/domain/scenarioCodeError.d.ts.map +1 -0
- package/dist/domain/scenarioCodeError.js +4 -0
- package/dist/domain/scenarioCodeError.js.map +1 -0
- package/dist/domain/scenarioReconciliation.d.ts +2 -207
- package/dist/domain/scenarioReconciliation.d.ts.map +1 -1
- package/dist/domain/scenarioReconciliation.js +4 -101
- package/dist/domain/scenarioReconciliation.js.map +1 -1
- package/dist/domain/scnAllocation.d.ts +27 -0
- package/dist/domain/scnAllocation.d.ts.map +1 -0
- package/dist/domain/scnAllocation.js +33 -0
- package/dist/domain/scnAllocation.js.map +1 -0
- package/dist/domain/verdictCode.d.ts +10 -0
- package/dist/domain/verdictCode.d.ts.map +1 -0
- package/dist/domain/verdictCode.js +16 -0
- package/dist/domain/verdictCode.js.map +1 -0
- package/dist/index.d.ts +14 -40
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -88
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +3 -27
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +3 -94
- package/dist/internal.js.map +1 -1
- package/dist/lib/bareTerm.d.ts +0 -39
- package/dist/lib/bareTerm.d.ts.map +1 -1
- package/dist/lib/bareTerm.js +0 -39
- package/dist/lib/bareTerm.js.map +1 -1
- package/dist/lib/portablePath.d.ts.map +1 -1
- package/dist/lib/portablePath.js +2 -16
- package/dist/lib/portablePath.js.map +1 -1
- package/dist/lib/scnCitation.d.ts +0 -32
- package/dist/lib/scnCitation.d.ts.map +1 -1
- package/dist/lib/scnCitation.js +2 -42
- package/dist/lib/scnCitation.js.map +1 -1
- package/dist/model.d.ts +0 -23
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +0 -23
- package/dist/model.js.map +1 -1
- package/dist/parse/checkScriptsRunInCI.d.ts +5 -168
- package/dist/parse/checkScriptsRunInCI.d.ts.map +1 -1
- package/dist/parse/checkScriptsRunInCI.js +11 -171
- package/dist/parse/checkScriptsRunInCI.js.map +1 -1
- package/dist/parse/ciStepRecord.d.ts +4 -118
- package/dist/parse/ciStepRecord.d.ts.map +1 -1
- package/dist/parse/ciStepRecord.js +18 -225
- package/dist/parse/ciStepRecord.js.map +1 -1
- package/dist/parse/commandRuns.d.ts +0 -39
- package/dist/parse/commandRuns.d.ts.map +1 -1
- package/dist/parse/commandRuns.js +6 -67
- package/dist/parse/commandRuns.js.map +1 -1
- package/dist/parse/cucumber.d.ts +0 -53
- package/dist/parse/cucumber.d.ts.map +1 -1
- package/dist/parse/cucumber.js +42 -146
- package/dist/parse/cucumber.js.map +1 -1
- package/dist/parse/discoveryScope.d.ts +1 -46
- package/dist/parse/discoveryScope.d.ts.map +1 -1
- package/dist/parse/discoveryScope.js +2 -57
- package/dist/parse/discoveryScope.js.map +1 -1
- package/dist/parse/fitnessCitations.d.ts +1 -72
- package/dist/parse/fitnessCitations.d.ts.map +1 -1
- package/dist/parse/fitnessCitations.js +3 -55
- package/dist/parse/fitnessCitations.js.map +1 -1
- package/dist/parse/reconcilerSteps.d.ts +0 -46
- package/dist/parse/reconcilerSteps.d.ts.map +1 -1
- package/dist/parse/reconcilerSteps.js +2 -64
- package/dist/parse/reconcilerSteps.js.map +1 -1
- package/dist/parse/runningFitnessFunctions.d.ts +9 -0
- package/dist/parse/runningFitnessFunctions.d.ts.map +1 -0
- package/dist/parse/runningFitnessFunctions.js +57 -0
- package/dist/parse/runningFitnessFunctions.js.map +1 -0
- package/dist/parse/scenarioCodeErrors.d.ts +11 -0
- package/dist/parse/scenarioCodeErrors.d.ts.map +1 -0
- package/dist/parse/scenarioCodeErrors.js +78 -0
- package/dist/parse/scenarioCodeErrors.js.map +1 -0
- package/dist/parse/scenarios.d.ts +3 -228
- package/dist/parse/scenarios.d.ts.map +1 -1
- package/dist/parse/scenarios.js +20 -457
- package/dist/parse/scenarios.js.map +1 -1
- package/dist/parse/stepAccounting.d.ts +0 -46
- package/dist/parse/stepAccounting.d.ts.map +1 -1
- package/dist/parse/stepAccounting.js +1 -55
- package/dist/parse/stepAccounting.js.map +1 -1
- package/dist/parse/stepExclusions.d.ts +0 -47
- package/dist/parse/stepExclusions.d.ts.map +1 -1
- package/dist/parse/stepExclusions.js +2 -50
- package/dist/parse/stepExclusions.js.map +1 -1
- package/dist/parse/stepNames.d.ts +0 -27
- package/dist/parse/stepNames.d.ts.map +1 -1
- package/dist/parse/stepNames.js +0 -27
- package/dist/parse/stepNames.js.map +1 -1
- package/dist/parse/targetCorpus.d.ts +1 -78
- package/dist/parse/targetCorpus.d.ts.map +1 -1
- package/dist/parse/targetCorpus.js +4 -46
- package/dist/parse/targetCorpus.js.map +1 -1
- package/dist/parse/targetManifest.d.ts +8 -146
- package/dist/parse/targetManifest.d.ts.map +1 -1
- package/dist/parse/targetManifest.js +48 -198
- package/dist/parse/targetManifest.js.map +1 -1
- package/dist/parse/vitest.d.ts +0 -60
- package/dist/parse/vitest.d.ts.map +1 -1
- package/dist/parse/vitest.js +4 -83
- package/dist/parse/vitest.js.map +1 -1
- package/dist/provenance/provenance.d.ts +2 -110
- package/dist/provenance/provenance.d.ts.map +1 -1
- package/dist/provenance/provenance.js +2 -58
- package/dist/provenance/provenance.js.map +1 -1
- package/dist/render/behaviouralRunners.d.ts +0 -29
- package/dist/render/behaviouralRunners.d.ts.map +1 -1
- package/dist/render/behaviouralRunners.js +6 -69
- package/dist/render/behaviouralRunners.js.map +1 -1
- package/dist/render/configurationNotRead.d.ts +3 -0
- package/dist/render/configurationNotRead.d.ts.map +1 -0
- package/dist/render/configurationNotRead.js +17 -0
- package/dist/render/configurationNotRead.js.map +1 -0
- package/dist/render/discoveryScope.d.ts +0 -37
- package/dist/render/discoveryScope.d.ts.map +1 -1
- package/dist/render/discoveryScope.js +3 -39
- package/dist/render/discoveryScope.js.map +1 -1
- package/dist/render/evidenceGrid.d.ts +1 -35
- package/dist/render/evidenceGrid.d.ts.map +1 -1
- package/dist/render/evidenceGrid.js +21 -103
- package/dist/render/evidenceGrid.js.map +1 -1
- package/dist/render/excludedSteps.d.ts +0 -26
- package/dist/render/excludedSteps.d.ts.map +1 -1
- package/dist/render/excludedSteps.js +4 -32
- package/dist/render/excludedSteps.js.map +1 -1
- package/dist/render/fitnessFunctions.d.ts +3 -0
- package/dist/render/fitnessFunctions.d.ts.map +1 -0
- package/dist/render/fitnessFunctions.js +12 -0
- package/dist/render/fitnessFunctions.js.map +1 -0
- package/dist/render/json.d.ts +0 -11
- package/dist/render/json.d.ts.map +1 -1
- package/dist/render/json.js +0 -11
- package/dist/render/json.js.map +1 -1
- package/dist/render/markdown.d.ts +1 -55
- package/dist/render/markdown.d.ts.map +1 -1
- package/dist/render/markdown.js +128 -467
- package/dist/render/markdown.js.map +1 -1
- package/dist/render/provenanceSection.d.ts +0 -22
- package/dist/render/provenanceSection.d.ts.map +1 -1
- package/dist/render/provenanceSection.js +10 -53
- package/dist/render/provenanceSection.js.map +1 -1
- package/dist/render/reconcilerSteps.d.ts +0 -25
- package/dist/render/reconcilerSteps.d.ts.map +1 -1
- package/dist/render/reconcilerSteps.js +5 -30
- package/dist/render/reconcilerSteps.js.map +1 -1
- package/dist/render/runVerdict.d.ts +0 -38
- package/dist/render/runVerdict.d.ts.map +1 -1
- package/dist/render/runVerdict.js +62 -129
- package/dist/render/runVerdict.js.map +1 -1
- package/dist/render/scenarioCodeErrorsSection.d.ts +3 -0
- package/dist/render/scenarioCodeErrorsSection.d.ts.map +1 -0
- package/dist/render/scenarioCodeErrorsSection.js +45 -0
- package/dist/render/scenarioCodeErrorsSection.js.map +1 -0
- package/dist/render/stepAccounting.d.ts +0 -36
- package/dist/render/stepAccounting.d.ts.map +1 -1
- package/dist/render/stepAccounting.js +5 -49
- package/dist/render/stepAccounting.js.map +1 -1
- package/dist/render/testVolume.d.ts +0 -25
- package/dist/render/testVolume.d.ts.map +1 -1
- package/dist/render/testVolume.js +4 -35
- package/dist/render/testVolume.js.map +1 -1
- package/package.json +4 -1
- package/dist/domain/checkCharacteristics.d.ts +0 -88
- package/dist/domain/checkCharacteristics.d.ts.map +0 -1
- package/dist/domain/checkCharacteristics.js +0 -109
- package/dist/domain/checkCharacteristics.js.map +0 -1
- package/dist/domain/fitnessChecks.d.ts +0 -79
- package/dist/domain/fitnessChecks.d.ts.map +0 -1
- package/dist/domain/fitnessChecks.js +0 -81
- package/dist/domain/fitnessChecks.js.map +0 -1
- package/dist/domain/qualityCheckFaultMessages.d.ts +0 -43
- package/dist/domain/qualityCheckFaultMessages.d.ts.map +0 -1
- package/dist/domain/qualityCheckFaultMessages.js +0 -38
- package/dist/domain/qualityCheckFaultMessages.js.map +0 -1
- package/dist/lib/featureCode.d.ts +0 -21
- package/dist/lib/featureCode.d.ts.map +0 -1
- package/dist/lib/featureCode.js +0 -24
- package/dist/lib/featureCode.js.map +0 -1
- package/dist/parse/corpusCodeFaults.d.ts +0 -76
- package/dist/parse/corpusCodeFaults.d.ts.map +0 -1
- package/dist/parse/corpusCodeFaults.js +0 -121
- package/dist/parse/corpusCodeFaults.js.map +0 -1
- package/dist/parse/corpusFaults.d.ts +0 -124
- package/dist/parse/corpusFaults.d.ts.map +0 -1
- package/dist/parse/corpusFaults.js +0 -72
- package/dist/parse/corpusFaults.js.map +0 -1
- package/dist/parse/corpusGrammarFaults.d.ts +0 -71
- package/dist/parse/corpusGrammarFaults.d.ts.map +0 -1
- package/dist/parse/corpusGrammarFaults.js +0 -292
- package/dist/parse/corpusGrammarFaults.js.map +0 -1
- package/dist/parse/runningStaticChecks.d.ts +0 -125
- package/dist/parse/runningStaticChecks.d.ts.map +0 -1
- package/dist/parse/runningStaticChecks.js +0 -316
- package/dist/parse/runningStaticChecks.js.map +0 -1
- package/dist/render/staticChecks.d.ts +0 -23
- package/dist/render/staticChecks.d.ts.map +0 -1
- package/dist/render/staticChecks.js +0 -69
- package/dist/render/staticChecks.js.map +0 -1
package/dist/lib/scnCitation.js
CHANGED
|
@@ -1,47 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* `describe`/`it` title. Sibling of `lib/featureCode.ts`, which owns the id GRAMMAR
|
|
4
|
-
* (`SCN-<FFF>-<NNN>`, Evidence Manifesto §9A); this owns the wrapper that turns a
|
|
5
|
-
* mention of that id into a citation.
|
|
6
|
-
*
|
|
7
|
-
* A citation is the BRACKETED token — `[SCN-<FFF>-<NNN>]`. Canon assigns the forms per
|
|
8
|
-
* backend (evidence-manifesto.md): "The Vitest `describe`/`it` string includes
|
|
9
|
-
* `[SCN-007]`; the Cucumber-JS step block carries a `// @SCN-007` marker comment." The
|
|
10
|
-
* `@` form is Cucumber's marker and is NOT a Vitest citation here — deliberately, and
|
|
11
|
-
* that exclusion is the rule's teeth: `@SCN-…` is how this repository writes every prose
|
|
12
|
-
* cross-reference, in comments, headers and ticket references, so accepting it in a title
|
|
13
|
-
* would leave the false-citation class open on the form most likely to appear by accident.
|
|
14
|
-
*
|
|
15
|
-
* Before this module the two citation readers each carried their own sigil-OPTIONAL regex
|
|
16
|
-
* — `/\bSCN-[A-Z0-9]+-\d+\b/` in parse/vitest.ts and `/@?(SCN-[A-Z0-9]+-\d+)/g` in
|
|
17
|
-
* tests/checks/scnSubIssueGate.ts — so any SCN-shaped token anywhere in a title was a
|
|
18
|
-
* citation whatever it was doing there. On the runtime side that minted a phantom scenario
|
|
19
|
-
* from fixture data; on the static side it let a prose mention vouch for a changed test
|
|
20
|
-
* block, a false green. Two copies of the answer is how they drifted from canon and from
|
|
21
|
-
* each other, so there is one copy now and both import it (3F-2368).
|
|
22
|
-
*/
|
|
23
|
-
/**
|
|
24
|
-
* The bracketed citation. Captures the bare code so callers get `SCN-<FFF>-<NNN>` with no
|
|
25
|
-
* wrapper. Intentionally NOT anchored — a title carries the citation among prose — and
|
|
26
|
-
* intentionally not `\b`-delimited, because the brackets are the delimiters.
|
|
27
|
-
*/
|
|
28
|
-
const SCN_CITATION = /\[(SCN-[A-Z0-9]+-\d+)\]/;
|
|
29
|
-
/** The same, globally, for callers reading every citation on a line. */
|
|
30
|
-
const SCN_CITATIONS = /\[(SCN-[A-Z0-9]+-\d+)\]/g;
|
|
31
|
-
/**
|
|
32
|
-
* The FIRST bracketed scenario id cited in `text`, as a bare code, or null when `text`
|
|
33
|
-
* cites none. An SCN-shaped token without its brackets is prose and yields null.
|
|
34
|
-
*/
|
|
1
|
+
import { SCN_ID_SOURCE } from "../domain/featureCode.js";
|
|
2
|
+
const SCN_CITATION = new RegExp(`\\[(${SCN_ID_SOURCE})\\]`);
|
|
35
3
|
export function parseScnCitation(text) {
|
|
36
4
|
const match = SCN_CITATION.exec(text);
|
|
37
5
|
return match ? match[1] : null;
|
|
38
6
|
}
|
|
39
|
-
/**
|
|
40
|
-
* EVERY bracketed scenario id cited in `text`, as bare codes, in document order and
|
|
41
|
-
* de-duplicated. The multi-citation read the scn-subissue gate needs, where one
|
|
42
|
-
* `describe` line may vouch for more than one scenario.
|
|
43
|
-
*/
|
|
44
|
-
export function parseScnCitations(text) {
|
|
45
|
-
return [...new Set([...text.matchAll(SCN_CITATIONS)].map((match) => match[1]))];
|
|
46
|
-
}
|
|
47
7
|
//# sourceMappingURL=scnCitation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scnCitation.js","sourceRoot":"","sources":["../../src/lib/scnCitation.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"scnCitation.js","sourceRoot":"","sources":["../../src/lib/scnCitation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,OAAO,aAAa,MAAM,CAAC,CAAC;AAE5D,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,CAAC"}
|
package/dist/model.d.ts
CHANGED
|
@@ -1,26 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The reconciliation data model — now a thin re-export of the co-located domain concept
|
|
3
|
-
* modules under `domain/**` (3F-1994, the DDD retrofit's Slice A). The types and their
|
|
4
|
-
* behaviour moved to the modules that OWN them — each concept co-locating its type with its
|
|
5
|
-
* pure free functions (module, not class):
|
|
6
|
-
* - `domain/journal.ts` — the debit/credit input concepts (evidence
|
|
7
|
-
* obligations, scenarios, evidence observations,
|
|
8
|
-
* pending items) + `evidenceObligationPairsOf`.
|
|
9
|
-
* - `domain/qualityCheckReconciliation.ts` — the reconciling item (`Outcome`,
|
|
10
|
-
* `OUTCOME_DESCRIPTION`, `OUT_OF_BALANCE_OUTCOMES`,
|
|
11
|
-
* `QualityCheckReconciliation`) +
|
|
12
|
-
* `reconcileEvidenceObligation`.
|
|
13
|
-
* - `domain/scenarioReconciliation.ts` — the account (`ScenarioReconciliation`,
|
|
14
|
-
* `ScenarioVerdict`, `ScenarioKind`) + `verdictFor` /
|
|
15
|
-
* `reconcilingItemsOf`.
|
|
16
|
-
* - `domain/ledger.ts` — the Ledger + the whole-run predicates.
|
|
17
|
-
*
|
|
18
|
-
* This module stays as the stable internal aggregation point (`../model.js`) so the many
|
|
19
|
-
* in-core importers and the public v1 barrel (`index.ts`) see the SAME surface —
|
|
20
|
-
* only the concepts' HOME moved. It is NOT a `domain/**` module itself (it re-exports across the
|
|
21
|
-
* concept modules, and it sits OUTSIDE `packages/core/src/domain/`, which is what `lint:boundaries`'s
|
|
22
|
-
* `domain-imports-adapter` rule is scoped to — the domain-purity guard's population until 3F-3438).
|
|
23
|
-
*/
|
|
24
1
|
export * from "./domain/journal.js";
|
|
25
2
|
export * from "./domain/qualityCheckReconciliation.js";
|
|
26
3
|
export * from "./domain/scenarioReconciliation.js";
|
package/dist/model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,oBAAoB,CAAC"}
|
package/dist/model.js
CHANGED
|
@@ -1,26 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The reconciliation data model — now a thin re-export of the co-located domain concept
|
|
3
|
-
* modules under `domain/**` (3F-1994, the DDD retrofit's Slice A). The types and their
|
|
4
|
-
* behaviour moved to the modules that OWN them — each concept co-locating its type with its
|
|
5
|
-
* pure free functions (module, not class):
|
|
6
|
-
* - `domain/journal.ts` — the debit/credit input concepts (evidence
|
|
7
|
-
* obligations, scenarios, evidence observations,
|
|
8
|
-
* pending items) + `evidenceObligationPairsOf`.
|
|
9
|
-
* - `domain/qualityCheckReconciliation.ts` — the reconciling item (`Outcome`,
|
|
10
|
-
* `OUTCOME_DESCRIPTION`, `OUT_OF_BALANCE_OUTCOMES`,
|
|
11
|
-
* `QualityCheckReconciliation`) +
|
|
12
|
-
* `reconcileEvidenceObligation`.
|
|
13
|
-
* - `domain/scenarioReconciliation.ts` — the account (`ScenarioReconciliation`,
|
|
14
|
-
* `ScenarioVerdict`, `ScenarioKind`) + `verdictFor` /
|
|
15
|
-
* `reconcilingItemsOf`.
|
|
16
|
-
* - `domain/ledger.ts` — the Ledger + the whole-run predicates.
|
|
17
|
-
*
|
|
18
|
-
* This module stays as the stable internal aggregation point (`../model.js`) so the many
|
|
19
|
-
* in-core importers and the public v1 barrel (`index.ts`) see the SAME surface —
|
|
20
|
-
* only the concepts' HOME moved. It is NOT a `domain/**` module itself (it re-exports across the
|
|
21
|
-
* concept modules, and it sits OUTSIDE `packages/core/src/domain/`, which is what `lint:boundaries`'s
|
|
22
|
-
* `domain-imports-adapter` rule is scoped to — the domain-purity guard's population until 3F-3438).
|
|
23
|
-
*/
|
|
24
1
|
export * from "./domain/journal.js";
|
|
25
2
|
export * from "./domain/qualityCheckReconciliation.js";
|
|
26
3
|
export * from "./domain/scenarioReconciliation.js";
|
package/dist/model.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,oBAAoB,CAAC"}
|
|
@@ -1,182 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The CI-parse primitive — the shared static-evidence reader machinery BOTH static-check
|
|
3
|
-
* observers import: walk the CI config STRUCTURALLY to its steps (`ciWorkflowSteps`, of which
|
|
4
|
-
* `ciRunSteps` is the projection to the `run:` ones and `ciRunCommands` the projection to their
|
|
5
|
-
* command strings), and test whether a command invokes
|
|
6
|
-
* a given npm script by an EXACT package-manager invocation (`commandInvokesScript`).
|
|
7
|
-
* `runningStaticChecks` (the running-check observer, and since 3F-3410 the only static-check
|
|
8
|
-
* observer) reads a check's enforcement off these, so the watermelon-critical parse lives in ONE
|
|
9
|
-
* place — a mis-read could itself HIDE a watermelon (read a severed static check as enforced, or
|
|
10
|
-
* the reverse).
|
|
11
|
-
*
|
|
12
|
-
* The CI config is parsed with the reputable `yaml` parser (jobs → steps → run, including
|
|
13
|
-
* block-scalar `run:` and `if:`/matrix steps) — never line-scanned. The step mapping is read
|
|
14
|
-
* for its `continue-on-error` and its `id:` as well as its `run:`, because a step whose red the job
|
|
15
|
-
* would swallow is a check that reports without enforcing (3F-3042, @SCN-LNT-032) and a step's
|
|
16
|
-
* `id:` is where a consumer writes the `@SCN` its check cites (3F-3261). A static check's
|
|
17
|
-
* command counts as enforced only on an EXACT
|
|
18
|
-
* package-manager invocation of its script name (`pnpm <script>` / `pnpm run <script>` /
|
|
19
|
-
* `npm run <script>` / `yarn <script>`), so a sibling static check's run step never falsely enforces it.
|
|
20
|
-
*
|
|
21
|
-
* Parent: @SCN-LNT-001.
|
|
22
|
-
*/
|
|
23
|
-
/** The minimal shape of `package.json` the static check observers depend on. */
|
|
24
1
|
export interface PackageJsonScripts {
|
|
25
2
|
scripts?: Record<string, string>;
|
|
26
3
|
}
|
|
27
|
-
|
|
28
|
-
* One CI `run:` step: the command, the `id:` it was given, and whether its red is the job's verdict.
|
|
29
|
-
*
|
|
30
|
-
* A UNION RATHER THAN AN OPTIONAL FIELD for the `continue-on-error` half, so the invariant is
|
|
31
|
-
* unrepresentable rather than commented. A step that does not abort the job always names the key
|
|
32
|
-
* that severs it — a reader has to know WHICH key to delete, and the two live in two different
|
|
33
|
-
* places — and a step that does abort it carries no such key to go stale beside the flag.
|
|
34
|
-
*
|
|
35
|
-
* `id` IS OPTIONAL AND THAT IS NOT THE SAME SHAPE OF QUESTION. There is no second key and no
|
|
36
|
-
* invariant to pair it with: the step either carries an `id:` or it does not, and its absence is a
|
|
37
|
-
* fact about the workflow rather than a state needing a witness. Optional rather than `string |
|
|
38
|
-
* null` for the reason the observation's own `scnId` is (`domain/journal.ts`) — an absent citation
|
|
39
|
-
* carries no key at all.
|
|
40
|
-
*
|
|
41
|
-
* @SCN-LNT-032 — features/fitness-reconciliation.feature.
|
|
42
|
-
*/
|
|
43
|
-
export type CiRunStep = {
|
|
44
|
-
readonly command: string;
|
|
45
|
-
readonly id?: string;
|
|
46
|
-
} & StepAbortsJob;
|
|
47
|
-
/**
|
|
48
|
-
* Whether a step's red is the job's verdict, and — when it is not — which key severed it.
|
|
49
|
-
*
|
|
50
|
-
* NAMED RATHER THAN INLINED because two step readings now carry it: `CiRunStep`, which is the
|
|
51
|
-
* `run:`-only projection every existing caller reads, and `CiWorkflowStep`, the whole-pipeline
|
|
52
|
-
* walk below. Restating the union in both would let the two drift into disagreeing about the one
|
|
53
|
-
* attribute that separates a gate from a gate in name only.
|
|
54
|
-
*/
|
|
55
|
-
type StepAbortsJob = {
|
|
56
|
-
readonly abortsJob: true;
|
|
57
|
-
} | {
|
|
58
|
-
readonly abortsJob: false;
|
|
59
|
-
/** Which key carries the `continue-on-error`, and the value it carries. */
|
|
60
|
-
readonly continuesOnError: {
|
|
61
|
-
readonly carriedBy: "step" | "job";
|
|
62
|
-
readonly value: string;
|
|
63
|
-
};
|
|
64
|
-
};
|
|
65
|
-
/**
|
|
66
|
-
* What a step DOES — GitHub gives a step one of these two and never both.
|
|
67
|
-
*
|
|
68
|
-
* A UNION RATHER THAN TWO OPTIONAL FIELDS, so "a step with neither" and "a step with both" are
|
|
69
|
-
* unrepresentable instead of being states every reader has to remember to handle.
|
|
70
|
-
*/
|
|
71
|
-
export type CiStepAction =
|
|
72
|
-
/** A shell step, carrying the command it runs. */
|
|
73
|
-
{
|
|
4
|
+
export type CiStepAction = {
|
|
74
5
|
readonly runs: string;
|
|
75
|
-
}
|
|
76
|
-
/** An action step, carrying the action reference it uses. */
|
|
77
|
-
| {
|
|
6
|
+
} | {
|
|
78
7
|
readonly uses: string;
|
|
79
8
|
};
|
|
80
|
-
/**
|
|
81
|
-
* ONE step of ONE job of ONE workflow — every step, whatever form it takes, with the identity a
|
|
82
|
-
* consumer would recognise it by and the job it belongs to.
|
|
83
|
-
*
|
|
84
|
-
* WHY THIS EXISTS BESIDE `CiRunStep` (3F-3352). Three things this walk has always seen and thrown
|
|
85
|
-
* away are each needed to report a pipeline rather than a subset of it: `uses:` steps (a quality
|
|
86
|
-
* check can be an action, so discarding them at the walk drops real checks), the step's `name:`
|
|
87
|
-
* (which is how a consumer identifies a step, and how a report names one), and the job the step
|
|
88
|
-
* belongs to (`Typecheck` in `ci.yml` and `Typecheck` in `release.yml` are otherwise
|
|
89
|
-
* indistinguishable, which makes a per-step exclusion unwritable).
|
|
90
|
-
*
|
|
91
|
-
* A SOURCE INDEX RATHER THAN A FILENAME. `ciSources` is an array of anonymous source strings and
|
|
92
|
-
* the core holds no filesystem — deliberately, and `ciSourcePaths.ts` says why. Mapping the index
|
|
93
|
-
* back to a workflow file is the CLI edge's job, where the paths are already resolved.
|
|
94
|
-
*/
|
|
95
9
|
export type CiWorkflowStep = {
|
|
96
|
-
/** Which of the `ciSources` this step was read from — an index, never a path. */
|
|
97
10
|
readonly sourceIndex: number;
|
|
98
|
-
/** The key this step's job is written under in the workflow's `jobs:` mapping. */
|
|
99
11
|
readonly jobId: string;
|
|
100
|
-
/** What GitHub itself would display for this step — see `identityOf`. */
|
|
101
12
|
readonly identity: string;
|
|
102
13
|
readonly id?: string;
|
|
103
|
-
/**
|
|
104
|
-
* The step's OWN `env:` values, as written — where a workflow EXPRESSION crosses into a step.
|
|
105
|
-
*
|
|
106
|
-
* WHY A READER WANTS THEM (3F-3358). A `${{ }}` expansion inside `run:` is substituted into the
|
|
107
|
-
* script before bash sees it, so a value carrying a quote would end the string and the rest
|
|
108
|
-
* would be shell; the way a workflow hands a step something GitHub computed is therefore `env:`,
|
|
109
|
-
* and this repository's own step-record dump says so in as many words. A reader that cannot see
|
|
110
|
-
* `env:` cannot tell a step producing the run's own step record from any other shell step.
|
|
111
|
-
*
|
|
112
|
-
* THE STEP'S OWN, NEVER THE JOB'S, and that is a narrowing rather than an omission. A job-level
|
|
113
|
-
* `env:` reaches every step of the job, so reading it here would answer this question the same
|
|
114
|
-
* way for all of them — and a reader that took an expression off the job would set the whole
|
|
115
|
-
* job aside on the strength of one key.
|
|
116
|
-
*
|
|
117
|
-
* VALUES, NOT KEYS. What a caller asks about is what a step was handed; the name a workflow gave
|
|
118
|
-
* it is the author's own word for it, and not one this walk has any business carrying.
|
|
119
|
-
*/
|
|
120
14
|
readonly env: readonly string[];
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
* Every CI `run:` step command across ALL of a target's config sources.
|
|
124
|
-
*
|
|
125
|
-
* A pipeline split across files — a nightly sweep, a security scan — enforces its checks
|
|
126
|
-
* just as a single file does, so "does this check run in CI" is a question about the whole
|
|
127
|
-
* set (3F-2238). Per-source, not joined: parse tolerance stays per document, so one
|
|
128
|
-
* malformed workflow costs only its own commands instead of discarding every other file's
|
|
129
|
-
* — joining first would widen the watermelon-hiding surface this parse exists to keep narrow.
|
|
130
|
-
*
|
|
131
|
-
* Sources, never paths: the caller reads the files, so no filesystem and no CI-provider
|
|
132
|
-
* layout enters the core.
|
|
133
|
-
*/
|
|
134
|
-
export declare function ciRunCommands(ciSources: readonly string[]): string[];
|
|
135
|
-
/**
|
|
136
|
-
* Every CI `run:` step across ALL of a target's config sources — the command, the `id:` it carries,
|
|
137
|
-
* and whether the step's red would abort the job.
|
|
138
|
-
*
|
|
139
|
-
* THE SAME WALK `ciRunCommands` READS, WIDENED — never a second one, and widened TWICE now for the
|
|
140
|
-
* same reason. `continue-on-error` and `id` are both keys of the step mapping this walk already
|
|
141
|
-
* visits and used to discard, and a second walk to pick either up would be a second thing to get
|
|
142
|
-
* wrong, disagreeing silently with the first about which steps a workflow even runs.
|
|
143
|
-
* `ciRunCommands` is this function's projection, so the two cannot disagree.
|
|
144
|
-
*
|
|
145
|
-
* WHY A CALLER WANTS `abortsJob` (3F-3042). A green CI run is evidence that every unconditional
|
|
146
|
-
* step ran, because a `run:` step that reds aborts the job. `continue-on-error` is the one
|
|
147
|
-
* attribute that falsifies that: the step runs, reds, and leaves the job green. A reader that
|
|
148
|
-
* cannot see it cannot tell a gate from a gate in name only.
|
|
149
|
-
*
|
|
150
|
-
* WHY A CALLER WANTS `id` (3F-3261). A check step's `id:` is where a consumer writes the `@SCN`
|
|
151
|
-
* their check cites — a citation, never a declaration: the obligation stays in the scenario and the
|
|
152
|
-
* command stays in the step. Reading it here is what lets the derivation say WHICH row a wired
|
|
153
|
-
* check answers, rather than only that it is wired.
|
|
154
|
-
*
|
|
155
|
-
* @SCN-LNT-032 — features/fitness-reconciliation.feature.
|
|
156
|
-
*/
|
|
157
|
-
export declare function ciRunSteps(ciSources: readonly string[]): CiRunStep[];
|
|
158
|
-
/**
|
|
159
|
-
* EVERY step across ALL of a target's config sources — `uses:` as well as `run:`, each with the
|
|
160
|
-
* identity GitHub displays for it, the job it belongs to, and the source it was read from.
|
|
161
|
-
*
|
|
162
|
-
* THE WALK, OF WHICH `ciRunSteps` IS NOW THE PROJECTION — never a second one, for the third time
|
|
163
|
-
* and the same reason. `uses:`, `name:` and the job key are all reachable from the mapping this
|
|
164
|
-
* walk already visits, and a sibling walk to pick them up would be free to disagree with this one
|
|
165
|
-
* about which steps a workflow even runs. `ciRunSteps` projects this, so the two cannot; that is
|
|
166
|
-
* the relationship `ciRunCommands` already has to `ciRunSteps`, one layer along.
|
|
167
|
-
*
|
|
168
|
-
* WHY A CALLER WANTS THE WIDER READING (3F-3352, parent 3F-3343). A pipeline's quality checks are
|
|
169
|
-
* whatever a consumer's pipeline runs, and a reader that discards every `uses:` step at the walk
|
|
170
|
-
* cannot see a check that is an action; one that forgets `name:` cannot report a step by the
|
|
171
|
-
* string its author reads in their own run log; and one that flattens the jobs cannot tell two
|
|
172
|
-
* identically-named steps in two workflows apart, which is what makes a per-step judgement about
|
|
173
|
-
* one of them unwritable.
|
|
174
|
-
*
|
|
175
|
-
* IT CHANGES NO VERDICT. Nothing is discovered, excluded or classified here — this reader makes
|
|
176
|
-
* the steps VISIBLE, and what is done with them is its callers'.
|
|
177
|
-
*/
|
|
15
|
+
readonly abortsJob: boolean;
|
|
16
|
+
} & CiStepAction;
|
|
178
17
|
export declare function ciWorkflowSteps(ciSources: readonly string[]): CiWorkflowStep[];
|
|
179
|
-
|
|
180
|
-
export declare function commandInvokesScript(command: string, guard: string): boolean;
|
|
181
|
-
export {};
|
|
18
|
+
export declare function commandInvokesScript(command: string, script: string): boolean;
|
|
182
19
|
//# sourceMappingURL=checkScriptsRunInCI.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkScriptsRunInCI.d.ts","sourceRoot":"","sources":["../../src/parse/checkScriptsRunInCI.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"checkScriptsRunInCI.d.ts","sourceRoot":"","sources":["../../src/parse/checkScriptsRunInCI.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAQD,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9B,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B,GAAG,YAAY,CAAC;AAuEjB,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,cAAc,EAAE,CAE9E;AAiBD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAE7E"}
|
|
@@ -1,87 +1,23 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The CI-parse primitive — the shared static-evidence reader machinery BOTH static-check
|
|
3
|
-
* observers import: walk the CI config STRUCTURALLY to its steps (`ciWorkflowSteps`, of which
|
|
4
|
-
* `ciRunSteps` is the projection to the `run:` ones and `ciRunCommands` the projection to their
|
|
5
|
-
* command strings), and test whether a command invokes
|
|
6
|
-
* a given npm script by an EXACT package-manager invocation (`commandInvokesScript`).
|
|
7
|
-
* `runningStaticChecks` (the running-check observer, and since 3F-3410 the only static-check
|
|
8
|
-
* observer) reads a check's enforcement off these, so the watermelon-critical parse lives in ONE
|
|
9
|
-
* place — a mis-read could itself HIDE a watermelon (read a severed static check as enforced, or
|
|
10
|
-
* the reverse).
|
|
11
|
-
*
|
|
12
|
-
* The CI config is parsed with the reputable `yaml` parser (jobs → steps → run, including
|
|
13
|
-
* block-scalar `run:` and `if:`/matrix steps) — never line-scanned. The step mapping is read
|
|
14
|
-
* for its `continue-on-error` and its `id:` as well as its `run:`, because a step whose red the job
|
|
15
|
-
* would swallow is a check that reports without enforcing (3F-3042, @SCN-LNT-032) and a step's
|
|
16
|
-
* `id:` is where a consumer writes the `@SCN` its check cites (3F-3261). A static check's
|
|
17
|
-
* command counts as enforced only on an EXACT
|
|
18
|
-
* package-manager invocation of its script name (`pnpm <script>` / `pnpm run <script>` /
|
|
19
|
-
* `npm run <script>` / `yarn <script>`), so a sibling static check's run step never falsely enforces it.
|
|
20
|
-
*
|
|
21
|
-
* Parent: @SCN-LNT-001.
|
|
22
|
-
*/
|
|
23
1
|
import { parse } from "yaml";
|
|
24
|
-
/** A non-null object — the YAML-parse walk narrows through these. */
|
|
25
2
|
function isRecord(v) {
|
|
26
3
|
return typeof v === "object" && v !== null;
|
|
27
4
|
}
|
|
28
|
-
/** The one key that severs a step's red from the job's verdict — GitHub spells it in two places. */
|
|
29
5
|
const CONTINUE_ON_ERROR = "continue-on-error";
|
|
30
|
-
/**
|
|
31
|
-
* Does a `continue-on-error` value leave a step's red as the job's verdict?
|
|
32
|
-
*
|
|
33
|
-
* THE SAFE DIRECTION, the one this walk already takes on a document it cannot parse at all:
|
|
34
|
-
* absent, `false`, or the string `"false"` vouches for a step and nothing else does. An
|
|
35
|
-
* expression's value is decided by the run rather than by the document, so a step this parse
|
|
36
|
-
* cannot PROVE will abort the job is a step it must not vouch for — the reading that reports a
|
|
37
|
-
* check unenforced (flagged) rather than falsely enforced (hidden).
|
|
38
|
-
*/
|
|
39
6
|
function vouchesForTheStep(value) {
|
|
40
7
|
return value === undefined || value === false || value === "false";
|
|
41
8
|
}
|
|
42
|
-
/**
|
|
43
|
-
* A step's own `env:` VALUES, or none — anything that is not a string is not an expression and is
|
|
44
|
-
* not something a reader here can be given, the same safe direction `idOf` below takes.
|
|
45
|
-
*/
|
|
46
9
|
function envValuesOf(value) {
|
|
47
|
-
return isRecord(value)
|
|
48
|
-
? Object.values(value).filter((entry) => typeof entry === "string")
|
|
49
|
-
: [];
|
|
10
|
+
return Object.values(isRecord(value) ? value : {}).filter((entry) => typeof entry === "string");
|
|
50
11
|
}
|
|
51
|
-
/**
|
|
52
|
-
* A step's `id:`, or nothing.
|
|
53
|
-
*
|
|
54
|
-
* A STRING OR SILENCE. YAML will hand back a number for `id: 001` and a mapping for a malformed
|
|
55
|
-
* one, and neither is something a citation can be read off — so anything but a non-empty string
|
|
56
|
-
* reads as no `id:` at all. The SAFE direction again: an unreadable `id:` leaves the step citing
|
|
57
|
-
* nothing, which posts to suspense and is visible, rather than citing a coerced word that would
|
|
58
|
-
* answer some obligation by accident.
|
|
59
|
-
*/
|
|
60
12
|
function idOf(value) {
|
|
61
13
|
if (typeof value !== "string")
|
|
62
14
|
return undefined;
|
|
63
15
|
const id = value.trim();
|
|
64
16
|
return id === "" ? undefined : id;
|
|
65
17
|
}
|
|
66
|
-
/** A step's own `continue-on-error` read against its job's. */
|
|
67
18
|
function abortsJobOf(ownValue, jobValue) {
|
|
68
|
-
|
|
69
|
-
// either alone is enough to sever the step, so this decides the message and not the verdict.
|
|
70
|
-
if (!vouchesForTheStep(ownValue)) {
|
|
71
|
-
return { abortsJob: false, continuesOnError: { carriedBy: "step", value: String(ownValue) } };
|
|
72
|
-
}
|
|
73
|
-
if (!vouchesForTheStep(jobValue)) {
|
|
74
|
-
return { abortsJob: false, continuesOnError: { carriedBy: "job", value: String(jobValue) } };
|
|
75
|
-
}
|
|
76
|
-
return { abortsJob: true };
|
|
19
|
+
return vouchesForTheStep(ownValue) && vouchesForTheStep(jobValue);
|
|
77
20
|
}
|
|
78
|
-
/**
|
|
79
|
-
* What a step does, or nothing at all.
|
|
80
|
-
*
|
|
81
|
-
* `run:` IS READ FIRST so that a malformed step carrying both keys is read exactly as this walk
|
|
82
|
-
* has always read it. A step carrying neither is not a step GitHub would run, and yields nothing
|
|
83
|
-
* — the same safe direction the rest of this parse takes on what it cannot make sense of.
|
|
84
|
-
*/
|
|
85
21
|
function actionOf(step) {
|
|
86
22
|
const runs = step["run"];
|
|
87
23
|
if (typeof runs === "string")
|
|
@@ -91,15 +27,6 @@ function actionOf(step) {
|
|
|
91
27
|
return { uses };
|
|
92
28
|
return undefined;
|
|
93
29
|
}
|
|
94
|
-
/**
|
|
95
|
-
* The string GitHub itself displays for a step: its `name:`, else the action it `uses:`, else the
|
|
96
|
-
* first line of its `run:`.
|
|
97
|
-
*
|
|
98
|
-
* IN GITHUB'S OWN ORDER AND FOR GITHUB'S OWN REASON — a consumer naming a step in configuration,
|
|
99
|
-
* or reading one off a report, reads the string already in front of them in their run log, so
|
|
100
|
-
* nothing new has to be learned to write one down. The first NON-BLANK line of a `run:`, because a
|
|
101
|
-
* block scalar may open on one and an empty identity is a string no consumer can write.
|
|
102
|
-
*/
|
|
103
30
|
function identityOf(name, action) {
|
|
104
31
|
if (typeof name === "string" && name.trim() !== "")
|
|
105
32
|
return name.trim();
|
|
@@ -107,10 +34,6 @@ function identityOf(name, action) {
|
|
|
107
34
|
return action.uses;
|
|
108
35
|
return action.runs.split(/\r?\n/).find((line) => line.trim() !== "")?.trim() ?? "";
|
|
109
36
|
}
|
|
110
|
-
/**
|
|
111
|
-
* The steps of ONE job. A job-level `continue-on-error` reaches every one of them, which
|
|
112
|
-
* is why the job's own key is read here rather than left to the step loop to miss.
|
|
113
|
-
*/
|
|
114
37
|
function stepsOfJob(jobId, job, sourceIndex) {
|
|
115
38
|
if (!isRecord(job))
|
|
116
39
|
return [];
|
|
@@ -125,134 +48,51 @@ function stepsOfJob(jobId, job, sourceIndex) {
|
|
|
125
48
|
const action = actionOf(step);
|
|
126
49
|
if (action === undefined)
|
|
127
50
|
continue;
|
|
128
|
-
const id = idOf(step["id"]);
|
|
129
51
|
read.push({
|
|
130
52
|
sourceIndex,
|
|
131
53
|
jobId,
|
|
132
54
|
identity: identityOf(step["name"], action),
|
|
133
55
|
env: envValuesOf(step["env"]),
|
|
134
|
-
|
|
135
|
-
// key at all — the shape an absent citation has everywhere else in this engine.
|
|
136
|
-
...(id !== undefined ? { id } : {}),
|
|
56
|
+
id: idOf(step["id"]),
|
|
137
57
|
...action,
|
|
138
|
-
|
|
58
|
+
abortsJob: abortsJobOf(step[CONTINUE_ON_ERROR], jobValue),
|
|
139
59
|
});
|
|
140
60
|
}
|
|
141
61
|
return read;
|
|
142
62
|
}
|
|
143
|
-
/**
|
|
144
|
-
* Every step of ONE config source, walked STRUCTURALLY from the parsed document
|
|
145
|
-
* (jobs → steps). A malformed config that fails to parse yields no steps — the SAFE
|
|
146
|
-
* direction: it reports static checks as unenforced (flagged), never falsely enforced (hidden).
|
|
147
|
-
*/
|
|
148
63
|
function stepsOf(ciSource, sourceIndex) {
|
|
149
64
|
let doc;
|
|
150
65
|
try {
|
|
151
66
|
doc = parse(ciSource);
|
|
152
67
|
}
|
|
153
68
|
catch {
|
|
154
|
-
|
|
69
|
+
// An unparseable workflow declares no steps, as one with no jobs does.
|
|
155
70
|
}
|
|
156
71
|
const jobs = isRecord(doc) ? doc["jobs"] : undefined;
|
|
157
72
|
if (!isRecord(jobs))
|
|
158
73
|
return [];
|
|
159
74
|
return Object.entries(jobs).flatMap(([jobId, job]) => stepsOfJob(jobId, job, sourceIndex));
|
|
160
75
|
}
|
|
161
|
-
/** One whole-pipeline step read back down to the `run:`-step shape its callers have always had. */
|
|
162
|
-
function runStepOf(step) {
|
|
163
|
-
const read = { command: step.runs, ...(step.id !== undefined ? { id: step.id } : {}) };
|
|
164
|
-
return step.abortsJob
|
|
165
|
-
? { ...read, abortsJob: true }
|
|
166
|
-
: { ...read, abortsJob: false, continuesOnError: step.continuesOnError };
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Every CI `run:` step command across ALL of a target's config sources.
|
|
170
|
-
*
|
|
171
|
-
* A pipeline split across files — a nightly sweep, a security scan — enforces its checks
|
|
172
|
-
* just as a single file does, so "does this check run in CI" is a question about the whole
|
|
173
|
-
* set (3F-2238). Per-source, not joined: parse tolerance stays per document, so one
|
|
174
|
-
* malformed workflow costs only its own commands instead of discarding every other file's
|
|
175
|
-
* — joining first would widen the watermelon-hiding surface this parse exists to keep narrow.
|
|
176
|
-
*
|
|
177
|
-
* Sources, never paths: the caller reads the files, so no filesystem and no CI-provider
|
|
178
|
-
* layout enters the core.
|
|
179
|
-
*/
|
|
180
|
-
export function ciRunCommands(ciSources) {
|
|
181
|
-
return ciRunSteps(ciSources).map((step) => step.command);
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Every CI `run:` step across ALL of a target's config sources — the command, the `id:` it carries,
|
|
185
|
-
* and whether the step's red would abort the job.
|
|
186
|
-
*
|
|
187
|
-
* THE SAME WALK `ciRunCommands` READS, WIDENED — never a second one, and widened TWICE now for the
|
|
188
|
-
* same reason. `continue-on-error` and `id` are both keys of the step mapping this walk already
|
|
189
|
-
* visits and used to discard, and a second walk to pick either up would be a second thing to get
|
|
190
|
-
* wrong, disagreeing silently with the first about which steps a workflow even runs.
|
|
191
|
-
* `ciRunCommands` is this function's projection, so the two cannot disagree.
|
|
192
|
-
*
|
|
193
|
-
* WHY A CALLER WANTS `abortsJob` (3F-3042). A green CI run is evidence that every unconditional
|
|
194
|
-
* step ran, because a `run:` step that reds aborts the job. `continue-on-error` is the one
|
|
195
|
-
* attribute that falsifies that: the step runs, reds, and leaves the job green. A reader that
|
|
196
|
-
* cannot see it cannot tell a gate from a gate in name only.
|
|
197
|
-
*
|
|
198
|
-
* WHY A CALLER WANTS `id` (3F-3261). A check step's `id:` is where a consumer writes the `@SCN`
|
|
199
|
-
* their check cites — a citation, never a declaration: the obligation stays in the scenario and the
|
|
200
|
-
* command stays in the step. Reading it here is what lets the derivation say WHICH row a wired
|
|
201
|
-
* check answers, rather than only that it is wired.
|
|
202
|
-
*
|
|
203
|
-
* @SCN-LNT-032 — features/fitness-reconciliation.feature.
|
|
204
|
-
*/
|
|
205
|
-
export function ciRunSteps(ciSources) {
|
|
206
|
-
return ciWorkflowSteps(ciSources).flatMap((step) => ("runs" in step ? [runStepOf(step)] : []));
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* EVERY step across ALL of a target's config sources — `uses:` as well as `run:`, each with the
|
|
210
|
-
* identity GitHub displays for it, the job it belongs to, and the source it was read from.
|
|
211
|
-
*
|
|
212
|
-
* THE WALK, OF WHICH `ciRunSteps` IS NOW THE PROJECTION — never a second one, for the third time
|
|
213
|
-
* and the same reason. `uses:`, `name:` and the job key are all reachable from the mapping this
|
|
214
|
-
* walk already visits, and a sibling walk to pick them up would be free to disagree with this one
|
|
215
|
-
* about which steps a workflow even runs. `ciRunSteps` projects this, so the two cannot; that is
|
|
216
|
-
* the relationship `ciRunCommands` already has to `ciRunSteps`, one layer along.
|
|
217
|
-
*
|
|
218
|
-
* WHY A CALLER WANTS THE WIDER READING (3F-3352, parent 3F-3343). A pipeline's quality checks are
|
|
219
|
-
* whatever a consumer's pipeline runs, and a reader that discards every `uses:` step at the walk
|
|
220
|
-
* cannot see a check that is an action; one that forgets `name:` cannot report a step by the
|
|
221
|
-
* string its author reads in their own run log; and one that flattens the jobs cannot tell two
|
|
222
|
-
* identically-named steps in two workflows apart, which is what makes a per-step judgement about
|
|
223
|
-
* one of them unwritable.
|
|
224
|
-
*
|
|
225
|
-
* IT CHANGES NO VERDICT. Nothing is discovered, excluded or classified here — this reader makes
|
|
226
|
-
* the steps VISIBLE, and what is done with them is its callers'.
|
|
227
|
-
*/
|
|
228
76
|
export function ciWorkflowSteps(ciSources) {
|
|
229
77
|
return ciSources.flatMap((ciSource, sourceIndex) => stepsOf(ciSource, sourceIndex));
|
|
230
78
|
}
|
|
231
|
-
|
|
232
|
-
* Does a single command LINE invoke the given npm script via a package manager?
|
|
233
|
-
* Matches `pnpm <guard>`, `pnpm run <guard>`, `npm run <guard>`, `yarn <guard>`
|
|
234
|
-
* on an EXACT script-name token — no fuzzy substring (a fuzzy match could hide a
|
|
235
|
-
* watermelon by treating a sibling static check's step as this static check's).
|
|
236
|
-
*/
|
|
237
|
-
function lineInvokesScript(line, guard) {
|
|
79
|
+
function lineInvokesScript(line, script) {
|
|
238
80
|
const tokens = line.trim().split(/\s+/);
|
|
239
|
-
for (
|
|
240
|
-
const tok = tokens[i];
|
|
81
|
+
for (const [i, tok] of tokens.entries()) {
|
|
241
82
|
if (tok === "pnpm" || tok === "yarn") {
|
|
242
83
|
let j = i + 1;
|
|
243
84
|
if (tokens[j] === "run")
|
|
244
85
|
j++;
|
|
245
|
-
if (tokens[j] ===
|
|
86
|
+
if (tokens[j] === script)
|
|
246
87
|
return true;
|
|
247
88
|
}
|
|
248
|
-
if (tok === "npm" && tokens[i + 1] === "run" && tokens[i + 2] ===
|
|
89
|
+
if (tok === "npm" && tokens[i + 1] === "run" && tokens[i + 2] === script) {
|
|
249
90
|
return true;
|
|
250
91
|
}
|
|
251
92
|
}
|
|
252
93
|
return false;
|
|
253
94
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
return command.split(/\r?\n/).some((line) => lineInvokesScript(line, guard));
|
|
95
|
+
export function commandInvokesScript(command, script) {
|
|
96
|
+
return command.split(/\r?\n/).some((line) => lineInvokesScript(line, script));
|
|
257
97
|
}
|
|
258
98
|
//# sourceMappingURL=checkScriptsRunInCI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkScriptsRunInCI.js","sourceRoot":"","sources":["../../src/parse/checkScriptsRunInCI.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"checkScriptsRunInCI.js","sourceRoot":"","sources":["../../src/parse/checkScriptsRunInCI.ts"],"names":[],"mappings":"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"}
|