@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
|
@@ -1,69 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
* IT ARRIVED HERE FROM `reconcile/` (3F-2232). After 3F-2202/2203/2204 that module held no domain
|
|
7
|
-
* rule — but it was still a named layer beside the domain doing the concept's own work, which is
|
|
8
|
-
* the shape `functional-domain-modelling.md` rejects: *"orchestration is thin composition, not a
|
|
9
|
-
* named layer."* Constructing a concept is the concept's business. The module's residual tell was
|
|
10
|
-
* already visible — it re-exported `isBalanced` / `hasPendingItems` / `hasBrokenEvidence` FROM
|
|
11
|
-
* `domain/ledger` purely to preserve importers' paths, a shell around behaviour that had already
|
|
12
|
-
* gone home. Every importer now points at the module that OWNS the symbol.
|
|
13
|
-
*
|
|
14
|
-
* (3F-2233 completes the move: the concept's TYPE, its `Summary`, and the factory that fuses this
|
|
15
|
-
* fold with the summary tally. Today this module holds the fold alone.)
|
|
16
|
-
*
|
|
17
|
-
* The pure obligation-vs-observation join, keyed by one flat
|
|
18
|
-
* `qualityCheck` (the two-axis `(kind, level)` grid collapsed). This module is THIN
|
|
19
|
-
* COMPOSITION: the domain RULES it once held moved to the
|
|
20
|
-
* concept modules that own them (3F-1994) — `reconcileEvidenceObligation` (the per-obligation
|
|
21
|
-
* outcome) to `domain/qualityCheckReconciliation`, `verdictFor` / `reconcilingItemsOf` (the
|
|
22
|
-
* account roll-up) to `domain/scenarioReconciliation`, `isBalanced` / `hasPendingItems` /
|
|
23
|
-
* `hasBrokenEvidence` (the whole-run predicates) to `domain/ledger`. `reconcile` is the fold that
|
|
24
|
-
* WALKS the inputs, CALLS those rules, and BUILDS the rows; it is the orchestration, not their home.
|
|
25
|
-
*
|
|
26
|
-
* POSTING-DESTINATION left too (3F-2202) — WHERE an entry lands is canon's own glossary group
|
|
27
|
-
* ("### Posting") and now lives on `domain/posting`: `postingOf`, the one citation route over both
|
|
28
|
-
* axes (plus the no-evidence-obligation-static-check arm). The by-name half is gone (3F-2590).
|
|
29
|
-
* The fold no longer DECIDES a destination anywhere — it
|
|
30
|
-
* asks the rule once per credit and files the answer. What remains is assembly: which rows exist,
|
|
31
|
-
* in what order, holding which items.
|
|
32
|
-
*
|
|
33
|
-
* Per the slice design: for each evidence obligation a scenario raises (a reconciling
|
|
34
|
-
* item), present+pass → satisfied; present+fail → failing; absent →
|
|
35
|
-
* missing. `reconcileEvidenceObligation` branches on the `qualityCheck === "lint"`
|
|
36
|
-
* watermelon discriminator (replacing the retired `kind === "static"` split): a `lint`
|
|
37
|
-
* evidence obligation reconciles against a static-check evidence observation (exists+wired → satisfied;
|
|
38
|
-
* exists+unwired → watermelon; absent → missing); a runtime evidence obligation
|
|
39
|
-
* reconciles against a test result matched by (scnId, quality-check).
|
|
40
|
-
*
|
|
41
|
-
* The scenario VERDICT is binary (superseding the earlier prioritising
|
|
42
|
-
* aggregate): a scenario is `balanced` IFF every required quality-check balances;
|
|
43
|
-
* otherwise `out-of-balance`, carrying the LIST of EVERY non-balanced reconciling
|
|
44
|
-
* item — no prioritisation, no picked winner ("missing beats failing" was a false
|
|
45
|
-
* order that hid one of two genuinely different problems). The renderers list
|
|
46
|
-
* every item.
|
|
47
|
-
*
|
|
48
|
-
* Parent: @SCN-LDG-001.
|
|
49
|
-
*/
|
|
50
|
-
import { evidenceObligationPairsOf,
|
|
51
|
-
// THE PENDING PARTITION (3F-2204) — the two exact complements over a scenario's obligations.
|
|
52
|
-
evidenceObligationsOf, pendingItemsOf, } from "../model.js";
|
|
53
|
-
import { reconcileEvidenceObligation,
|
|
54
|
-
// THE CREDIT-SIDE AND DEGENERATE OUTCOME RULES (3F-2204) — what an entry reconciles TO, as
|
|
55
|
-
// opposed to where it lands. `reconcile` asks; it no longer maps outcomes itself.
|
|
56
|
-
noEvidenceObligationReconciliationsOf, citesUnknownScenarioReconciliationsOf, suspenseReconciliationsOf, noScnCodeReconciliations, unspecifiedRowReconciliations, } from "./qualityCheckReconciliation.js";
|
|
57
|
-
import { ledgerTally, runtimeObservationTally, staticObservationTally, } from "./ledger.js";
|
|
58
|
-
import { verdictFor, reconcilingItemsOf,
|
|
59
|
-
// THE ROW-SHAPE RULE (3F-2204) — the both-missing degeneration and its pending clause.
|
|
60
|
-
qualityCheckReconciliationsOf, } from "./scenarioReconciliation.js";
|
|
61
|
-
// THE POSTING RULE (3F-2202) — where an entry lands is canon's own glossary group, so it lives on
|
|
62
|
-
// its own concept module. `reconcile` no longer decides a destination; it ASKS.
|
|
1
|
+
import { evidenceObligationPairsOf, evidenceObligationsOf, pendingItemsOf, } from "./journal.js";
|
|
2
|
+
import { reconcileEvidenceObligation, noEvidenceObligationReconciliationsOf, citesUnknownScenarioReconciliationsOf, suspenseReconciliationsOf, noScnCodeReconciliations, duplicateScnCodeReconciliationsOf, } from "./qualityCheckReconciliation.js";
|
|
3
|
+
import { ledgerTally, runtimeObservationTally, fitnessFunctionTally, } from "./ledger.js";
|
|
4
|
+
import { verdictFor, reconcilingItemsOf, qualityCheckReconciliationsOf, } from "./scenarioReconciliation.js";
|
|
63
5
|
import { postingOf } from "./posting.js";
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
import {
|
|
6
|
+
import { CORE_MESSAGES, CoreMessage } from "./messages.js";
|
|
7
|
+
import { inEvidenceOrder } from "./evidenceOrder.js";
|
|
8
|
+
import { isFitnessObservation } from "./journal.js";
|
|
67
9
|
function citationIndex() {
|
|
68
10
|
const byScn = new Map();
|
|
69
11
|
const phantomIds = [];
|
|
@@ -80,164 +22,99 @@ function citationIndex() {
|
|
|
80
22
|
phantomIds,
|
|
81
23
|
};
|
|
82
24
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
25
|
+
function routeFitnessCredit(observation, posting, citations, streams) {
|
|
26
|
+
if (posting.kind !== "suspense-scenario") {
|
|
27
|
+
citations.file(posting, observation);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (posting.posted === "broken" && isFitnessObservation(observation)) {
|
|
31
|
+
streams.brokenEvidence.push(observation);
|
|
32
|
+
}
|
|
33
|
+
else
|
|
34
|
+
streams.noEvidenceObligationFitnessFunctions.push(observation);
|
|
35
|
+
}
|
|
36
|
+
function routeRuntimeCredit(observation, posting, citations, streams) {
|
|
37
|
+
switch (posting.kind) {
|
|
38
|
+
case "scenario":
|
|
39
|
+
case "phantom-scenario": {
|
|
40
|
+
citations.file(posting, observation);
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
case "suspense-scenario":
|
|
44
|
+
if (posting.posted === "broken")
|
|
45
|
+
streams.brokenEvidence.push(observation);
|
|
46
|
+
else
|
|
47
|
+
streams.uncited.push(observation);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
98
51
|
function routeCredits(evidenceObservations, scenarioIds) {
|
|
99
|
-
// THE CITATION INDEX holds BOTH axes now (@SCN-LNT-001): a fitness check's run cites the
|
|
100
|
-
// scenario that raises its obligation, so it files here exactly as a test result does.
|
|
101
52
|
const citations = citationIndex();
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const brokenEvidence = [];
|
|
109
|
-
const uncited = [];
|
|
110
|
-
const noEvidenceObligationGuards = [];
|
|
53
|
+
const streams = {
|
|
54
|
+
brokenEvidence: [],
|
|
55
|
+
uncited: [],
|
|
56
|
+
noEvidenceObligationFitnessFunctions: [],
|
|
57
|
+
};
|
|
58
|
+
const { brokenEvidence, uncited, noEvidenceObligationFitnessFunctions } = streams;
|
|
111
59
|
for (const o of evidenceObservations) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
// on both branches.
|
|
115
|
-
if (o.qualityCheck === "lint") {
|
|
116
|
-
const posting = postingOf(o, scenarioIds);
|
|
117
|
-
// THE SPLIT ON THIS AXIS TOO (@SCN-LNT-026), the twin of the runtime arm's below. Both
|
|
118
|
-
// reasons post to suspense because neither names a row, and they stay in separate streams
|
|
119
|
-
// because they are different facts with different remedies: a check nobody named RAN and
|
|
120
|
-
// wants an obligation written for it; a broken one never ran and wants its harness fixed.
|
|
121
|
-
//
|
|
122
|
-
// THE SECOND CLAUSE IS THE NARROW, NOT A SECOND DECISION. `postingOf` reaches `broken` on
|
|
123
|
-
// this axis only through `isStaticCheckObservation`, so asking the same predicate here
|
|
124
|
-
// cannot disagree with it — it re-states what the rule already settled in the one form the
|
|
125
|
-
// compiler accepts. Nothing falls between the two arms: an observation that somehow took
|
|
126
|
-
// neither still lands in the second, misfiled rather than vaporised.
|
|
127
|
-
if (posting.kind === "suspense-scenario") {
|
|
128
|
-
if (posting.posted === "broken" && isStaticCheckObservation(o))
|
|
129
|
-
brokenEvidence.push(o);
|
|
130
|
-
else
|
|
131
|
-
noEvidenceObligationGuards.push(o);
|
|
132
|
-
}
|
|
133
|
-
// A CITING run files into the citation index like any other credit (@SCN-LNT-001) —
|
|
134
|
-
// exactly one row, real or invented. There is no third destination left (3F-2590).
|
|
135
|
-
else
|
|
136
|
-
citations.file(posting, o);
|
|
60
|
+
if (o.qualityCheck === "fitness") {
|
|
61
|
+
routeFitnessCredit(o, postingOf(o, scenarioIds), citations, streams);
|
|
137
62
|
continue;
|
|
138
63
|
}
|
|
139
|
-
|
|
140
|
-
switch (posting.kind) {
|
|
141
|
-
case "scenario":
|
|
142
|
-
case "phantom-scenario": {
|
|
143
|
-
// THE CITATION INDEX holds real AND invented ids alike — a phantom row reads its posted
|
|
144
|
-
// credits from here too, so both citation-routed destinations file together.
|
|
145
|
-
citations.file(posting, o);
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
case "suspense-scenario":
|
|
149
|
-
// THE SPLIT (@SCN-LDG-017) — `broken` and `cites-nothing` both land on suspense because
|
|
150
|
-
// neither names a scenario, but they are different facts with different remedies (fix the
|
|
151
|
-
// harness vs add the @SCN), so their streams stay apart. The rule already told them apart.
|
|
152
|
-
if (posting.posted === "broken")
|
|
153
|
-
brokenEvidence.push(o);
|
|
154
|
-
else
|
|
155
|
-
uncited.push(o);
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
64
|
+
routeRuntimeCredit(o, postingOf(o, scenarioIds), citations, streams);
|
|
158
65
|
}
|
|
159
|
-
return { citations, brokenEvidence, uncited,
|
|
66
|
+
return { citations, brokenEvidence, uncited, noEvidenceObligationFitnessFunctions };
|
|
160
67
|
}
|
|
161
|
-
/**
|
|
162
|
-
* ONE REAL SCENARIO'S ROW — the debit side reconciled against the observed evidence, the credit
|
|
163
|
-
* side's no-evidence-obligation items beside it, and the row assembled from both.
|
|
164
|
-
*
|
|
165
|
-
* ITS OWN FUNCTION, extracted at @SCN-LNT-027 (3F-3472) when the fourth population took `reconcile`
|
|
166
|
-
* past the `max-lines-per-function` ceiling — `routeCredits`' own precedent, and the same seam.
|
|
167
|
-
* Routing is one idea with a name, what each population RECONCILES to is another, and `reconcile`
|
|
168
|
-
* is the ORDER they are filed in. Nothing any of them decides moved.
|
|
169
|
-
*/
|
|
170
68
|
function scenarioRow(d, evidenceObservations, citations, evidenceObligationPairs) {
|
|
171
|
-
// THE PENDING PARTITION (@SCN-PND-004) — `pendingItemsOf` and `evidenceObligationsOf`
|
|
172
|
-
// are exact complements over the scenario's obligations, so nothing is dropped and nothing is
|
|
173
|
-
// counted twice. Rule + rationale: `domain/journal`.
|
|
174
69
|
const pendingItems = pendingItemsOf(d);
|
|
175
|
-
|
|
176
|
-
const reconciledEvidenceObligations = evidenceObligationsOf(d.evidenceObligations).map((req) => reconcileEvidenceObligation(d.scnId, req, evidenceObservations));
|
|
177
|
-
// The CREDIT side — NO-EVIDENCE-OBLIGATION (@SCN-LDG-008): a credit citing THIS real scenario at a
|
|
178
|
-
// quality-check it never named. Rule + rationale: `domain/qualityCheckReconciliation`.
|
|
70
|
+
const reconciledEvidenceObligations = evidenceObligationsOf(d.evidenceObligations).map((obligation) => reconcileEvidenceObligation(d.scnId, obligation, evidenceObservations));
|
|
179
71
|
const noEvidenceObligationItems = noEvidenceObligationReconciliationsOf(d.scnId, citations.creditsFor(d.scnId), evidenceObligationPairs);
|
|
180
|
-
// The row's SUB-ROWS, degenerating to one `both-missing` item when the row reconciled to
|
|
181
|
-
// nothing either way (@SCN-LDG-009). Rule + rationale: `domain/scenarioReconciliation`.
|
|
182
72
|
const qualityCheckReconciliations = qualityCheckReconciliationsOf(reconciledEvidenceObligations, noEvidenceObligationItems, pendingItems);
|
|
183
73
|
return {
|
|
184
74
|
scnId: d.scnId,
|
|
185
75
|
kind: "scenario",
|
|
186
76
|
verdict: verdictFor(qualityCheckReconciliations),
|
|
187
|
-
// THE POSTED CREDITS (@SCN-LDG-022) — every credit CITING this scenario, whatever it
|
|
188
|
-
// reconciles to above. The citation index holds every citing credit, so this includes one citing a
|
|
189
|
-
// PENDING quality-check, which reconciles `no-evidence-obligation` (3F-1858 — it used to reconcile to
|
|
190
|
-
// NO ROW AT ALL, the false-green this posting made visible without fixing). It posts and is
|
|
191
|
-
// findable WHATEVER it reconciles to; posting is not classifying, and a misclassification
|
|
192
|
-
// must misfile an entry, never vaporise it. A fitness check's run is in here too and by the
|
|
193
|
-
// SAME route (3F-2590): it cites this scenario, so the citation index holds it like any other.
|
|
194
77
|
evidenceObservations: citations.creditsFor(d.scnId),
|
|
195
|
-
// THE POSTED DEBITS (@SCN-LDG-023) — every obligation THIS scenario RAISES, in document
|
|
196
|
-
// order, keyed by quality-check. The debit half of the same posting: where a credit is
|
|
197
|
-
// routed by its citation, a debit needs no routing at all — the account IS the scenario.
|
|
198
|
-
// Includes a PENDING obligation, which partitioned off above and earns NO reconciled row: it
|
|
199
|
-
// posts ANYWAY. Posting is not classifying, on this side too.
|
|
200
78
|
evidenceObligations: [...d.evidenceObligations],
|
|
201
79
|
qualityCheckReconciliations,
|
|
202
80
|
reconcilingItems: reconcilingItemsOf(qualityCheckReconciliations),
|
|
203
81
|
pendingItems,
|
|
204
82
|
};
|
|
205
83
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
84
|
+
function accountsByCode(scenarios) {
|
|
85
|
+
const byCode = new Map();
|
|
86
|
+
for (const scenario of scenarios) {
|
|
87
|
+
const sharers = byCode.get(scenario.scnId) ?? [];
|
|
88
|
+
sharers.push(scenario);
|
|
89
|
+
byCode.set(scenario.scnId, sharers);
|
|
90
|
+
}
|
|
91
|
+
return [...byCode.values()];
|
|
92
|
+
}
|
|
93
|
+
function duplicateScnCodeRow(sharers, citations) {
|
|
94
|
+
const scnId = sharers[0].scnId;
|
|
95
|
+
const evidenceObligations = sharers.flatMap((s) => s.evidenceObligations);
|
|
96
|
+
const items = duplicateScnCodeReconciliationsOf(evidenceObligations);
|
|
97
|
+
return {
|
|
98
|
+
scnId,
|
|
99
|
+
kind: "scenario",
|
|
100
|
+
verdict: verdictFor(items),
|
|
101
|
+
evidenceObservations: citations.creditsFor(scnId),
|
|
102
|
+
evidenceObligations,
|
|
103
|
+
qualityCheckReconciliations: items,
|
|
104
|
+
reconcilingItems: reconcilingItemsOf(items),
|
|
105
|
+
pendingItems: [],
|
|
106
|
+
};
|
|
107
|
+
}
|
|
210
108
|
function phantomScenarioRows(citations) {
|
|
211
109
|
const rows = [];
|
|
212
|
-
// CREDIT-SIDE — PHANTOM scenarios (@SCN-LDG-006). One phantom Scenario Reconciliation per
|
|
213
|
-
// UNKNOWN cited id, in first-seen order, its Quality Check Reconciliation(s) carrying the
|
|
214
|
-
// outcome `cites-unknown-scenario` (and the evidence observation's locator, ruling Q5), verdict
|
|
215
|
-
// ALWAYS out-of-balance. Grouped AFTER the scenario rows.
|
|
216
|
-
//
|
|
217
|
-
// `phantomIds` was ROUTED ABOVE (3F-2202) — this block only ASSEMBLES the rows. The scan that
|
|
218
|
-
// stood here re-stated the citation index's four routing decisions verbatim, including the
|
|
219
|
-
// fail-safe arms (a BROKEN credit mints no phantom row; an uncited credit is suspense, never
|
|
220
|
-
// phantom); both now come from the one `postingOf` call.
|
|
221
110
|
for (const scnId of citations.phantomIds) {
|
|
222
111
|
const credits = citations.creditsFor(scnId);
|
|
223
|
-
// ASKED, not decided (3F-2204).
|
|
224
112
|
const items = citesUnknownScenarioReconciliationsOf(credits);
|
|
225
113
|
rows.push({
|
|
226
114
|
scnId,
|
|
227
115
|
kind: "phantom-scenario",
|
|
228
|
-
// ASKED, not restated (3F-2204, the close-gate read). Canon says a phantom row is ALWAYS
|
|
229
|
-
// out-of-balance, and it is — BY CONSTRUCTION, because a phantom row exists only where a
|
|
230
|
-
// credit minted it, so it always carries ≥1 `cites-unknown-scenario` item. Deriving the
|
|
231
|
-
// verdict from the items keeps that a consequence of the rule rather than a constant asserted
|
|
232
|
-
// beside it: a hardcoded verdict would go on reading `out-of-balance` even if the row ever
|
|
233
|
-
// came to carry none, which is precisely the drift the verdict/items lock-step exists to stop.
|
|
234
116
|
verdict: verdictFor(items),
|
|
235
|
-
// The credits that CITE this invented scenario post to it — canon organises the ledger by
|
|
236
|
-
// "real or INVENTED scenario", so a phantom account holds its postings like any other.
|
|
237
117
|
evidenceObservations: [...credits],
|
|
238
|
-
// A phantom account is MINTED BY A CREDIT — no scenario raises it, so nothing can have
|
|
239
|
-
// been named of it. Its debit side is empty by construction (@SCN-LDG-023); the asymmetry
|
|
240
|
-
// with the credit side is real, not an omission.
|
|
241
118
|
evidenceObligations: [],
|
|
242
119
|
qualityCheckReconciliations: items,
|
|
243
120
|
reconcilingItems: items,
|
|
@@ -246,33 +123,15 @@ function phantomScenarioRows(citations) {
|
|
|
246
123
|
}
|
|
247
124
|
return rows;
|
|
248
125
|
}
|
|
249
|
-
|
|
250
|
-
* THE SUSPENSE ROW, assembled (@SCN-LDG-007) — nil rows or one. Extracted beside its siblings at
|
|
251
|
-
* 3F-3472; what lands on it is `routeCredits`' decision, and unchanged.
|
|
252
|
-
*/
|
|
253
|
-
function suspenseScenarioRows(brokenEvidence, uncited, noEvidenceObligationGuards) {
|
|
126
|
+
function suspenseScenarioRows(brokenEvidence, uncited, noEvidenceObligationFitnessFunctions) {
|
|
254
127
|
const rows = [];
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
//
|
|
258
|
-
// Its three streams were ROUTED by the posting rule (3F-2202); their OUTCOMES and their ORDER
|
|
259
|
-
// are the item concept's (3F-2204, `suspenseReconciliationsOf` — rule + rationale there). What
|
|
260
|
-
// is decided HERE is only whether the row exists at all: suspense is minted by a credit landing
|
|
261
|
-
// on it, so no credit means no row.
|
|
262
|
-
if (brokenEvidence.length > 0 || uncited.length > 0 || noEvidenceObligationGuards.length > 0) {
|
|
263
|
-
const items = suspenseReconciliationsOf(brokenEvidence, uncited, noEvidenceObligationGuards);
|
|
128
|
+
if (brokenEvidence.length > 0 || uncited.length > 0 || noEvidenceObligationFitnessFunctions.length > 0) {
|
|
129
|
+
const items = suspenseReconciliationsOf(brokenEvidence, uncited, noEvidenceObligationFitnessFunctions);
|
|
264
130
|
rows.push({
|
|
265
|
-
scnId:
|
|
131
|
+
scnId: CORE_MESSAGES[CoreMessage.SuspenseScenarioId],
|
|
266
132
|
kind: "suspense-scenario",
|
|
267
|
-
// ASKED, not restated — same reason as the phantom row. The `if` above is what makes this
|
|
268
|
-
// out-of-balance by construction: the row exists only when a credit landed on it.
|
|
269
133
|
verdict: verdictFor(items),
|
|
270
|
-
|
|
271
|
-
// named no test, so it cites nothing whatever scnId it structurally carries), and the
|
|
272
|
-
// no-evidence-obligation static checks. With the citation index this exhausts the credit stream.
|
|
273
|
-
evidenceObservations: [...brokenEvidence, ...uncited, ...noEvidenceObligationGuards],
|
|
274
|
-
// Suspense is MINTED BY A CREDIT too — it raises nothing, so it names nothing
|
|
275
|
-
// (@SCN-LDG-023). It can therefore carry no Pending Item either.
|
|
134
|
+
evidenceObservations: [...brokenEvidence, ...uncited, ...noEvidenceObligationFitnessFunctions],
|
|
276
135
|
evidenceObligations: [],
|
|
277
136
|
qualityCheckReconciliations: items,
|
|
278
137
|
reconcilingItems: items,
|
|
@@ -281,32 +140,15 @@ function suspenseScenarioRows(brokenEvidence, uncited, noEvidenceObligationGuard
|
|
|
281
140
|
}
|
|
282
141
|
return rows;
|
|
283
142
|
}
|
|
284
|
-
/**
|
|
285
|
-
* THE UNCODED-WORK ROWS, assembled (@SCN-LDG-021). Extracted beside its siblings at 3F-3472.
|
|
286
|
-
*/
|
|
287
143
|
function untaggedScenarioRows(untaggedScenarios) {
|
|
288
144
|
const rows = [];
|
|
289
|
-
// UNCODED WORK (@SCN-LDG-021) — a scenario carrying no @SCN. It is REAL and ORDINARY
|
|
290
|
-
// (`kind: "scenario"`, never phantom or suspense: it exists, and cucumber runs it); what is
|
|
291
|
-
// absent is the CODE its obligation needs in order to link to an observation. It gets its own
|
|
292
|
-
// out-of-balance row so the verdict can see it at all.
|
|
293
|
-
//
|
|
294
|
-
// The item's outcome, its scenario-scope shape and the synthesised `{}` obligation it carries
|
|
295
|
-
// are the item concept's (3F-2204, `noScnCodeReconciliations` — rule + rationale there).
|
|
296
145
|
for (const name of untaggedScenarios) {
|
|
297
146
|
const items = noScnCodeReconciliations();
|
|
298
147
|
rows.push({
|
|
299
|
-
// The scenario's NAME is its only handle — it has no code. (Precedent: the suspense row's
|
|
300
|
-
// "(no scenario)" sentinel; `featureCodeOf` falls back to the raw id when it cannot parse.)
|
|
301
148
|
scnId: name,
|
|
302
149
|
kind: "scenario",
|
|
303
|
-
// ASKED, not restated — `noScnCodeReconciliations` always returns the one `no-scn-code`
|
|
304
|
-
// item, so the verdict follows from it rather than being asserted alongside it.
|
|
305
150
|
verdict: verdictFor(items),
|
|
306
|
-
// An untagged scenario carries no @SCN, so no credit can cite it — nothing can post here.
|
|
307
151
|
evidenceObservations: [],
|
|
308
|
-
// It reaches the ledger by NAME, carrying no parsed obligations — so it posts no debits
|
|
309
|
-
// either (@SCN-LDG-023).
|
|
310
152
|
evidenceObligations: [],
|
|
311
153
|
qualityCheckReconciliations: items,
|
|
312
154
|
reconcilingItems: items,
|
|
@@ -315,184 +157,47 @@ function untaggedScenarioRows(untaggedScenarios) {
|
|
|
315
157
|
}
|
|
316
158
|
return rows;
|
|
317
159
|
}
|
|
318
|
-
|
|
319
|
-
* THE ROWS A CONFIGURED ROW WITH NO SCENARIO EARNS, assembled (@SCN-LNT-027, 3F-3472).
|
|
320
|
-
*/
|
|
321
|
-
function unspecifiedFitnessRowRows(unspecifiedFitnessRows) {
|
|
322
|
-
const rows = [];
|
|
323
|
-
// A CONFIGURED ROW THE CORPUS CARRIES NO SCENARIO FOR (@SCN-LNT-027, 3F-3472) — a check the
|
|
324
|
-
// target's manifest declares and nothing in its corpus specifies. The obligations travel with
|
|
325
|
-
// the scenarios, so such a row raised NOTHING: it was not `missing`, not phantom, not suspense,
|
|
326
|
-
// and a tree carrying one reconciled balanced at exit 0 over a check declared and never written.
|
|
327
|
-
// `features/fitness-checks.feature` promises the opposite in terms — "a row whose scenario the
|
|
328
|
-
// corpus does not carry as an Evidence Obligation nothing observed" — and this is that promise.
|
|
329
|
-
//
|
|
330
|
-
// THE PRECEDENT IS UNCODED WORK, three lines up: a fact the ordinary obligation path cannot raise
|
|
331
|
-
// reaches the ledger by a reading of its own and gets its own out-of-balance row so the verdict
|
|
332
|
-
// can see it at all. There the CORPUS supplies a row the obligations cannot; here the MANIFEST
|
|
333
|
-
// does.
|
|
334
|
-
//
|
|
335
|
-
// THE ROW IS NOT IN `scenarioIds`, WHICH IS WHAT MAKES IT UNDISCHARGEABLE. That set was built
|
|
336
|
-
// from `scenarios` alone and is not widened here, so a credit citing this row's code still mints
|
|
337
|
-
// a PHANTOM row (@SCN-LDG-006, @SCN-LNT-009) and a broken credit still lands on SUSPENSE — and
|
|
338
|
-
// there is no route left by which any credit settles this debit. Synthesising a `Scenario` for
|
|
339
|
-
// the row instead would have put it INTO that set, so a run whose CI step cited a declared-but-
|
|
340
|
-
// unwritten check would reconcile BALANCED: a new false green, in the case the phantom row
|
|
341
|
-
// already covers.
|
|
342
|
-
for (const row of unspecifiedFitnessRows) {
|
|
343
|
-
const items = unspecifiedRowReconciliations(row.characteristic);
|
|
344
|
-
rows.push({
|
|
345
|
-
scnId: row.scnId,
|
|
346
|
-
kind: "scenario",
|
|
347
|
-
// ASKED, not restated — the phantom and suspense rows' rule. `unspecifiedRowReconciliations`
|
|
348
|
-
// always returns the one `missing` item, so the verdict follows from it.
|
|
349
|
-
verdict: verdictFor(items),
|
|
350
|
-
// No scenario carries this code, so the citation router posts no credit here — see above.
|
|
351
|
-
evidenceObservations: [],
|
|
352
|
-
// THE DEBIT IS REAL AND IS POSTED (@SCN-LDG-023). Unlike the untagged row above, which
|
|
353
|
-
// reaches the ledger by name and names no check, this row names exactly one characteristic:
|
|
354
|
-
// that is the obligation, and the manifest is what raised it.
|
|
355
|
-
evidenceObligations: [...items.map((item) => item.evidenceObligation)],
|
|
356
|
-
qualityCheckReconciliations: items,
|
|
357
|
-
reconcilingItems: items,
|
|
358
|
-
pendingItems: [],
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
return rows;
|
|
362
|
-
}
|
|
363
|
-
export function reconcile(scenarios, evidenceObservations, untaggedScenarios = [],
|
|
364
|
-
/**
|
|
365
|
-
* The CONFIGURED ROWS the target's corpus carries no scenario for (@SCN-LNT-027, 3F-3472) — the
|
|
366
|
-
* fourth population, minted below.
|
|
367
|
-
*
|
|
368
|
-
* IT DEFAULTS, WHERE THE TWO GATES BELOW DELIBERATELY DO NOT (3F-2875). A gate that defaults is a
|
|
369
|
-
* gate a caller can forget and thereby CHANGE what the summary claims. This is a population, and
|
|
370
|
-
* an omitted population is indistinguishable from an empty one in the only way that matters:
|
|
371
|
-
* both mint no rows, and neither says anything about a manifest. Every caller that constructs
|
|
372
|
-
* `Scenario[]` by hand has no manifest to read rows from, which is `untaggedScenarios`' own
|
|
373
|
-
* argument for the default it already carries.
|
|
374
|
-
*/
|
|
375
|
-
unspecifiedFitnessRows = []) {
|
|
376
|
-
// THE OBLIGATION SIDE, prepared once — the three sets the posting rule and the outcome rules read.
|
|
377
|
-
// Each is already the MODEL's own rule (never re-derived here), and each is built ONCE and
|
|
378
|
-
// shared, so no two consumers can drift: `scenarioIds` is which scenarios exist,
|
|
379
|
-
// and `evidenceObligationPairs` is what they name at each quality-check (3F-1858).
|
|
160
|
+
export function reconcile(scenarios, evidenceObservations, untaggedScenarios = []) {
|
|
380
161
|
const scenarioIds = new Set(scenarios.map((d) => d.scnId));
|
|
381
|
-
// The NAMED pairs — the model's rule, built ONCE and shared with the census (3F-1858).
|
|
382
|
-
// Pending obligations are excluded: a pending obligation names nothing.
|
|
383
162
|
const evidenceObligationPairs = evidenceObligationPairsOf(scenarios);
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
const { citations, brokenEvidence, uncited, noEvidenceObligationGuards } = routeCredits(evidenceObservations, scenarioIds);
|
|
387
|
-
// THE ORDER THE POPULATIONS ARE FILED IN IS THE LEDGER'S GROUPING, and it is the whole of what
|
|
388
|
-
// this function decides now: the real scenario rows, then the phantom rows a credit invented,
|
|
389
|
-
// then the one suspense row, then uncoded work, then the configured rows no scenario specifies.
|
|
163
|
+
const observations = inEvidenceOrder(evidenceObservations);
|
|
164
|
+
const { citations, brokenEvidence, uncited, noEvidenceObligationFitnessFunctions } = routeCredits(observations, scenarioIds);
|
|
390
165
|
return {
|
|
391
166
|
scenarioReconciliations: [
|
|
392
|
-
...scenarios.map((
|
|
167
|
+
...accountsByCode(scenarios).map((sharers) => sharers.length === 1
|
|
168
|
+
? scenarioRow(sharers[0], observations, citations, evidenceObligationPairs)
|
|
169
|
+
: duplicateScnCodeRow(sharers, citations)),
|
|
393
170
|
...phantomScenarioRows(citations),
|
|
394
|
-
...suspenseScenarioRows(brokenEvidence, uncited,
|
|
171
|
+
...suspenseScenarioRows(brokenEvidence, uncited, noEvidenceObligationFitnessFunctions),
|
|
395
172
|
...untaggedScenarioRows(untaggedScenarios),
|
|
396
|
-
...unspecifiedFitnessRowRows(unspecifiedFitnessRows),
|
|
397
173
|
],
|
|
398
174
|
};
|
|
399
175
|
}
|
|
400
|
-
|
|
401
|
-
* Materialise the summary totals from the balance — the aggregate the markdown's trial-balance
|
|
402
|
-
* table derives, carried AS DATA so a later render-from-saved-JSON rebuilds it with zero
|
|
403
|
-
* computation (the MATERIALISE ruling). THIN COMPOSITION (3F-2000): the LEDGER-PURE totals
|
|
404
|
-
* (`scenarioReconciliations`, `evidenceObligations`, `pending`, `lint`) come from `ledgerTally`
|
|
405
|
-
* — the Ledger owns its own totals ("the summary is its totals") — and are MERGED here with the
|
|
406
|
-
* census pass-throughs (`testVolume`, `staticChecks`), which are NOT Ledger-pure. The keys are
|
|
407
|
-
* assembled in DOCUMENT ORDER (…, testVolume?, staticChecks?, lint) so the JSON stays
|
|
408
|
-
* byte-identical.
|
|
409
|
-
*/
|
|
410
|
-
export function summaryOf(ledger, withRuntimeObservations, withStaticChecks) {
|
|
176
|
+
export function summaryOf(ledger, withRuntimeObservations, withFitnessFunctions) {
|
|
411
177
|
const tally = ledgerTally(ledger);
|
|
412
|
-
// The runtime evidence-observation totals are a FOLD OVER THE LEDGER (@SCN-RMD-003, 3F-2102) —
|
|
413
|
-
// the Ledger counts its own posted credits; the parallel census is RETIRED. `testVolume` and the
|
|
414
|
-
// re-homed `rawByRuntimeQualityCheck` derive from THIS fold. The `withRuntimeObservations` flag is
|
|
415
|
-
// now only the GATE (is the runtime-observation axis in play?) — the caller no longer threads a
|
|
416
|
-
// census object at all (the assembler folds the Ledger it already has).
|
|
417
178
|
const observations = runtimeObservationTally(ledger);
|
|
418
|
-
|
|
419
|
-
// posted static-check credits; the parallel static census is RETIRED. `staticChecks` derives from
|
|
420
|
-
// THIS fold. The `withStaticChecks` flag is now only the GATE (is the static-check axis in play?) —
|
|
421
|
-
// the caller no longer threads a census object at all (the assembler folds the Ledger it holds).
|
|
422
|
-
const staticChecks = staticObservationTally(ledger);
|
|
179
|
+
const fitnessFunctions = fitnessFunctionTally(ledger);
|
|
423
180
|
return {
|
|
424
181
|
scenarioReconciliations: tally.scenarioReconciliations,
|
|
425
182
|
evidenceObligations: tally.evidenceObligations,
|
|
426
183
|
pending: tally.pending,
|
|
427
|
-
// The runtime test-volume kind-counts (RMD-005), materialised only when the evidenceObservations
|
|
428
|
-
// read is threaded. The surface reads the fold's per-scenario-kind counts DIRECTLY (an identity
|
|
429
|
-
// — the fold already groups by the scenario-kind the credit posted to). `onScenario` is every
|
|
430
|
-
// credit posted to a scenario's account, which INCLUDES no-evidence-obligation as a subset
|
|
431
|
-
// (matched-pair + no-evidence-obligation) — a DIFFERENT number from the reconciliation-matched-attributed
|
|
432
|
-
// (the retired section's `attributed[]` sum, which excluded no-evidence-obligation). Keeping no-evidence-obligation
|
|
433
|
-
// inside this count preserves the 3-termed identity `totalEvidenceObservations = onScenario +
|
|
434
|
-
// onPhantomScenario + onSuspenseScenario` (no-evidence-obligation is a subset here, NOT a 4th identity term)
|
|
435
|
-
// — the same shape the markdown's `### Test volume` line derives. `onPhantomScenario` /
|
|
436
|
-
// `onSuspenseScenario` are the credits posted to the phantom / suspense accounts (suspense
|
|
437
|
-
// includes `broken`).
|
|
438
184
|
...(withRuntimeObservations
|
|
439
185
|
? {
|
|
440
186
|
testVolume: {
|
|
441
|
-
// ASKED, not re-derived (3F-2231) — the Ledger's fold computes this total and now
|
|
442
|
-
// returns it. The assembler summed the same record again for it, which is an adapter
|
|
443
|
-
// owning a model number by copied arithmetic.
|
|
444
187
|
totalEvidenceObservations: observations.total,
|
|
445
188
|
onScenario: observations.onScenario,
|
|
446
189
|
onPhantomScenario: observations.onPhantomScenario,
|
|
447
190
|
onSuspenseScenario: observations.onSuspenseScenario,
|
|
448
191
|
},
|
|
449
|
-
// The re-homed raw per-quality-check headline (@SCN-RMD-003) — a materialised Ledger
|
|
450
|
-
// fold, sibling of `testVolume` and present on the SAME gate.
|
|
451
192
|
rawByRuntimeQualityCheck: observations.rawByRuntimeQualityCheck,
|
|
452
193
|
}
|
|
453
194
|
: {}),
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
// runtime `testVolume` fold. The surface keeps the census shape exactly
|
|
457
|
-
// (`{ runningStaticCheckCount, uncitedStaticCheckCount }`; named is implicit). The member detail
|
|
458
|
-
// lives in the rows (named → each scenario's `@lint` sub-row; no-evidence-obligation → the suspense
|
|
459
|
-
// row) — there is no census section (2.4).
|
|
460
|
-
...(withStaticChecks ? { staticChecks } : {}),
|
|
461
|
-
// The static-only lint tally (RMD-005), a LEDGER-PURE derive from `ledgerTally` — LAST key in
|
|
462
|
-
// document order (after the census pass-throughs).
|
|
463
|
-
lint: tally.lint,
|
|
195
|
+
...(withFitnessFunctions ? { fitnessFunctions } : {}),
|
|
196
|
+
fitness: tally.fitness,
|
|
464
197
|
};
|
|
465
198
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
* Journal inputs in, whole concept out: the fold posts every entry into the Ledger, and the tally
|
|
470
|
-
* totals it. They are ONE act, not two stages a caller sequences — which is the point. While
|
|
471
|
-
* `reconcile()` and `buildSummary()` were separate, an adapter held a Ledger and derived its own
|
|
472
|
-
* totals, so "the procedure can sum the wrong rows" (`why-ddd-for-spec-controller.md`) was a
|
|
473
|
-
* REACHABLE state. Here there is no such seam: you cannot obtain a summary except from the concept
|
|
474
|
-
* that owns the rows it counts.
|
|
475
|
-
*
|
|
476
|
-
* The two flags are GATES, not data — they state whether the runtime-observation and static-check
|
|
477
|
-
* axes are in play for this run; the counts themselves are always folded from the Ledger.
|
|
478
|
-
*
|
|
479
|
-
* WHY THE TRAILING THREE ARE REQUIRED AND CARRY NO DEFAULTS (3F-2875). A gate that defaults to
|
|
480
|
-
* `false` is a gate a caller can forget to state, and forgetting it CHANGES THE REPORT — the
|
|
481
|
-
* summary then claims neither axis is in play, silently and plausibly. That is not a hypothetical:
|
|
482
|
-
* when the defaults were removed, eleven call sites turned out to have been leaning on them. Every
|
|
483
|
-
* one wanted exactly what it had been getting, so nothing moved; what changed is that each now says
|
|
484
|
-
* so. A default is the wrong shape for an argument whose omission is indistinguishable from a
|
|
485
|
-
* deliberate `false`.
|
|
486
|
-
*/
|
|
487
|
-
export function evidenceReconciliationOf(scenarios, evidenceObservations, untaggedScenarios, withRuntimeObservations, withStaticChecks,
|
|
488
|
-
/**
|
|
489
|
-
* The CONFIGURED ROWS the corpus carries no scenario for (@SCN-LNT-027, 3F-3472) — passed
|
|
490
|
-
* through to `reconcile`, which mints one row apiece. It defaults for the reason given there, and
|
|
491
|
-
* that reason is NOT the trailing three's: a population omitted mints nothing and claims nothing,
|
|
492
|
-
* where a gate omitted silently changes what the summary says is in play.
|
|
493
|
-
*/
|
|
494
|
-
unspecifiedFitnessRows = []) {
|
|
495
|
-
const ledger = reconcile(scenarios, evidenceObservations, untaggedScenarios, unspecifiedFitnessRows);
|
|
496
|
-
return { summary: summaryOf(ledger, withRuntimeObservations, withStaticChecks), ledger };
|
|
199
|
+
export function evidenceReconciliationOf(scenarios, evidenceObservations, untaggedScenarios, withRuntimeObservations, withFitnessFunctions) {
|
|
200
|
+
const ledger = reconcile(scenarios, evidenceObservations, untaggedScenarios);
|
|
201
|
+
return { summary: summaryOf(ledger, withRuntimeObservations, withFitnessFunctions), ledger };
|
|
497
202
|
}
|
|
498
203
|
//# sourceMappingURL=evidenceReconciliation.js.map
|