spec-controller 0.1.0-alpha.1 → 0.1.0-alpha.2
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 +94 -0
- package/dist/cli-args.d.ts +73 -0
- package/dist/cli-args.d.ts.map +1 -0
- package/dist/cli-args.js +114 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli-balance/cli.d.ts +2 -19
- package/dist/cli-balance/cli.d.ts.map +1 -1
- package/dist/cli-balance/cli.js +76 -78
- package/dist/cli-balance/cli.js.map +1 -1
- package/dist/cli-balance/emit/writer.d.ts +1 -1
- package/dist/cli-registry.d.ts +35 -12
- package/dist/cli-registry.d.ts.map +1 -1
- package/dist/cli-registry.js +93 -33
- package/dist/cli-registry.js.map +1 -1
- package/dist/cli.d.ts +5 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +9 -3
- package/dist/cli.js.map +1 -1
- package/dist/corpus/cli.d.ts +34 -0
- package/dist/corpus/cli.d.ts.map +1 -0
- package/dist/corpus/cli.js +128 -0
- package/dist/corpus/cli.js.map +1 -0
- package/dist/deferralTags.d.ts +1 -1
- package/dist/deferralTags.js +1 -1
- package/dist/ingest/gherkinValidation.d.ts +23 -0
- package/dist/ingest/gherkinValidation.d.ts.map +1 -1
- package/dist/ingest/gherkinValidation.js +27 -0
- package/dist/ingest/gherkinValidation.js.map +1 -1
- package/dist/ingest/ingestQualityChecks.d.ts +17 -2
- package/dist/ingest/ingestQualityChecks.d.ts.map +1 -1
- package/dist/ingest/ingestQualityChecks.js +94 -39
- package/dist/ingest/ingestQualityChecks.js.map +1 -1
- package/dist/ingest/ingestScenarios.d.ts +2 -1
- package/dist/ingest/ingestScenarios.d.ts.map +1 -1
- package/dist/ingest/ingestScenarios.js +32 -3
- package/dist/ingest/ingestScenarios.js.map +1 -1
- package/dist/mutation-ratchet/index.d.ts +36 -38
- package/dist/mutation-ratchet/index.d.ts.map +1 -1
- package/dist/mutation-ratchet/index.js +35 -37
- package/dist/mutation-ratchet/index.js.map +1 -1
- package/dist/mutation-ratchet/record.d.ts +21 -53
- package/dist/mutation-ratchet/record.d.ts.map +1 -1
- package/dist/mutation-ratchet/record.js +28 -44
- package/dist/mutation-ratchet/record.js.map +1 -1
- package/dist/mutation-ratchet/report.d.ts +31 -5
- package/dist/mutation-ratchet/report.d.ts.map +1 -1
- package/dist/mutation-ratchet/report.js +11 -3
- package/dist/mutation-ratchet/report.js.map +1 -1
- package/package.json +7 -2
- package/dist/mutation-ratchet/ratchet.d.ts +0 -129
- package/dist/mutation-ratchet/ratchet.d.ts.map +0 -1
- package/dist/mutation-ratchet/ratchet.js +0 -222
- package/dist/mutation-ratchet/ratchet.js.map +0 -1
- package/dist/mutation-ratchet/ratchetCli.d.ts +0 -57
- package/dist/mutation-ratchet/ratchetCli.d.ts.map +0 -1
- package/dist/mutation-ratchet/ratchetCli.js +0 -139
- package/dist/mutation-ratchet/ratchetCli.js.map +0 -1
- package/dist/mutation-ratchet/reconcile.d.ts +0 -82
- package/dist/mutation-ratchet/reconcile.d.ts.map +0 -1
- package/dist/mutation-ratchet/reconcile.js +0 -67
- package/dist/mutation-ratchet/reconcile.js.map +0 -1
- package/dist/mutation-ratchet/verdict.d.ts +0 -177
- package/dist/mutation-ratchet/verdict.d.ts.map +0 -1
- package/dist/mutation-ratchet/verdict.js +0 -387
- package/dist/mutation-ratchet/verdict.js.map +0 -1
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* THE COMPOSITION — one gate's run reconciled against its record, with every term a project owns
|
|
3
|
-
* arriving from that project (@SCN-RAT-014, 3F-2804).
|
|
4
|
-
*
|
|
5
|
-
* FIVE TERMS, AND FOUR OF THEM ARE WHY THIS MODULE EXISTS RATHER THAN A CALLER WIRING THE PIECES
|
|
6
|
-
* TOGETHER ITSELF. The reader, the report and the verdict below were each built generic, and the
|
|
7
|
-
* reference implementation this library was lifted from was generic in all of them too — right up
|
|
8
|
-
* to the point where something had to say WHICH tree, WHICH file, WHICH report and WHAT to type
|
|
9
|
-
* next. Those four answers were written into the code there, and they are the four that arrive
|
|
10
|
-
* here as a request instead.
|
|
11
|
-
*
|
|
12
|
-
* THE ROOT IS THE CONSUMER'S WORKSPACE, NEVER THIS MODULE'S OWN LOCATION, and that is the term
|
|
13
|
-
* that fails silently rather than loudly. A module finding the tree from where it is installed
|
|
14
|
-
* agrees with its caller for exactly as long as it sits beside that caller's code — which it does
|
|
15
|
-
* in the repository it was written in, and stops doing the day it is installed as a dependency,
|
|
16
|
-
* when it resolves into its own directory inside a package folder and finds nothing there. There
|
|
17
|
-
* is no way to notice from inside: the paths are well-formed, the reads fail as absent files, and
|
|
18
|
-
* a gate that measured perfectly reads as a gate that never ran. So the root arrives, and every
|
|
19
|
-
* path below is joined onto it.
|
|
20
|
-
*
|
|
21
|
-
* THE RECORD FILE IS DEFAULTED AND THE REPORT PATH IS NOT, and the asymmetry is a ruling rather
|
|
22
|
-
* than an oversight. Where a mutation sweep drops its output is a RUNNER'S convention, so a
|
|
23
|
-
* default there would be this module naming a runner — the exact leak the Rule above it forbids.
|
|
24
|
-
* The record's name is owned by whoever owns the record, so a conventional default costs its
|
|
25
|
-
* owner nothing and a caller who wants another writes one.
|
|
26
|
-
*
|
|
27
|
-
* AND THE BANK-IT INSTRUCTION IS CARRIED WHOLE, because the two verdicts that ask for a record to
|
|
28
|
-
* be banked have to say what to type, and what to type is a sentence only the calling project can
|
|
29
|
-
* write. Left to this module it would be somebody's script name, sitting inside a message, reached
|
|
30
|
-
* only on the runs nobody reads twice.
|
|
31
|
-
*
|
|
32
|
-
* NOTHING HERE NAMES A PROJECT, A CHECK, A RUNNER, A WORKFLOW OR A REPOSITORY, and @SCN-RAT-014
|
|
33
|
-
* asserts that over this module's own bytes rather than trusting it.
|
|
34
|
-
*/
|
|
35
|
-
import { type MutationVerdict } from "./verdict.js";
|
|
36
|
-
/**
|
|
37
|
-
* The name a record is filed under when its caller does not choose one.
|
|
38
|
-
*
|
|
39
|
-
* A DEFAULT, NEVER A CONSTANT THE READER GOES LOOKING FOR. Which file holds a project's bars is
|
|
40
|
-
* that project's own fact, and a caller naming its own is answered by that name — this is only
|
|
41
|
-
* what stands in when none is given, and it is exported so a caller happy with the convention does
|
|
42
|
-
* not have to respell it and get one character of it wrong.
|
|
43
|
-
*/
|
|
44
|
-
export declare const RECORD_FILE = "quality-thresholds.yml";
|
|
45
|
-
/**
|
|
46
|
-
* One reconciliation, as the calling project states it.
|
|
47
|
-
*
|
|
48
|
-
* EVERY FIELD IS A TERM THE PROJECT OWNS. There is nothing else here — no setting, no mode, no
|
|
49
|
-
* threshold of this module's own. The bar is in the project's record and the run is in the
|
|
50
|
-
* project's report; what this asks for is where those two are and what to call things.
|
|
51
|
-
*/
|
|
52
|
-
export interface RatchetRequest {
|
|
53
|
-
/** The gate to reconcile, as the project's own record names it. */
|
|
54
|
-
readonly gate: string;
|
|
55
|
-
/**
|
|
56
|
-
* The CONSUMER'S workspace — the tree the record and the report both sit in.
|
|
57
|
-
*
|
|
58
|
-
* Never this module's own installed location, which is the same tree only by coincidence and
|
|
59
|
-
* only until the day this ships as something another repository installs.
|
|
60
|
-
*/
|
|
61
|
-
readonly root: string;
|
|
62
|
-
/**
|
|
63
|
-
* Where the gate's run left its report, relative to that root.
|
|
64
|
-
*
|
|
65
|
-
* REQUIRED, AND THAT IS THE RULING. A default here would be a runner's output convention wearing
|
|
66
|
-
* this module's name.
|
|
67
|
-
*/
|
|
68
|
-
readonly reportPath: string;
|
|
69
|
-
/** What the project's own people type to bank a measurement, carried into the verdicts that ask. */
|
|
70
|
-
readonly bankCommand: string;
|
|
71
|
-
/** Where the project's record sits, relative to that root. Defaults to {@link RECORD_FILE}. */
|
|
72
|
-
readonly recordFile?: string;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Reconcile one gate's run against the bar its project's record states.
|
|
76
|
-
*
|
|
77
|
-
* @param request the five terms the calling project owns
|
|
78
|
-
* @returns the verdict, red or green, carrying the line its reader gets
|
|
79
|
-
* @throws MalformedRecordError when the record cannot be read as a bar, or holds no such gate
|
|
80
|
-
*/
|
|
81
|
-
export declare function reconcileGate(request: RatchetRequest): MutationVerdict;
|
|
82
|
-
//# sourceMappingURL=reconcile.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/mutation-ratchet/reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAOH,OAAO,EAA6B,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/E;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,2BAA2B,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,oGAAoG;IACpG,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,+FAA+F;IAC/F,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,eAAe,CAWtE"}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* THE COMPOSITION — one gate's run reconciled against its record, with every term a project owns
|
|
3
|
-
* arriving from that project (@SCN-RAT-014, 3F-2804).
|
|
4
|
-
*
|
|
5
|
-
* FIVE TERMS, AND FOUR OF THEM ARE WHY THIS MODULE EXISTS RATHER THAN A CALLER WIRING THE PIECES
|
|
6
|
-
* TOGETHER ITSELF. The reader, the report and the verdict below were each built generic, and the
|
|
7
|
-
* reference implementation this library was lifted from was generic in all of them too — right up
|
|
8
|
-
* to the point where something had to say WHICH tree, WHICH file, WHICH report and WHAT to type
|
|
9
|
-
* next. Those four answers were written into the code there, and they are the four that arrive
|
|
10
|
-
* here as a request instead.
|
|
11
|
-
*
|
|
12
|
-
* THE ROOT IS THE CONSUMER'S WORKSPACE, NEVER THIS MODULE'S OWN LOCATION, and that is the term
|
|
13
|
-
* that fails silently rather than loudly. A module finding the tree from where it is installed
|
|
14
|
-
* agrees with its caller for exactly as long as it sits beside that caller's code — which it does
|
|
15
|
-
* in the repository it was written in, and stops doing the day it is installed as a dependency,
|
|
16
|
-
* when it resolves into its own directory inside a package folder and finds nothing there. There
|
|
17
|
-
* is no way to notice from inside: the paths are well-formed, the reads fail as absent files, and
|
|
18
|
-
* a gate that measured perfectly reads as a gate that never ran. So the root arrives, and every
|
|
19
|
-
* path below is joined onto it.
|
|
20
|
-
*
|
|
21
|
-
* THE RECORD FILE IS DEFAULTED AND THE REPORT PATH IS NOT, and the asymmetry is a ruling rather
|
|
22
|
-
* than an oversight. Where a mutation sweep drops its output is a RUNNER'S convention, so a
|
|
23
|
-
* default there would be this module naming a runner — the exact leak the Rule above it forbids.
|
|
24
|
-
* The record's name is owned by whoever owns the record, so a conventional default costs its
|
|
25
|
-
* owner nothing and a caller who wants another writes one.
|
|
26
|
-
*
|
|
27
|
-
* AND THE BANK-IT INSTRUCTION IS CARRIED WHOLE, because the two verdicts that ask for a record to
|
|
28
|
-
* be banked have to say what to type, and what to type is a sentence only the calling project can
|
|
29
|
-
* write. Left to this module it would be somebody's script name, sitting inside a message, reached
|
|
30
|
-
* only on the runs nobody reads twice.
|
|
31
|
-
*
|
|
32
|
-
* NOTHING HERE NAMES A PROJECT, A CHECK, A RUNNER, A WORKFLOW OR A REPOSITORY, and @SCN-RAT-014
|
|
33
|
-
* asserts that over this module's own bytes rather than trusting it.
|
|
34
|
-
*/
|
|
35
|
-
import { readFileSync } from "node:fs";
|
|
36
|
-
import { join } from "node:path";
|
|
37
|
-
import { gateRecordFor, parseGateRecords } from "./record.js";
|
|
38
|
-
import { readMutationReport } from "./report.js";
|
|
39
|
-
import { noMeasurement, verdictFor } from "./verdict.js";
|
|
40
|
-
/**
|
|
41
|
-
* The name a record is filed under when its caller does not choose one.
|
|
42
|
-
*
|
|
43
|
-
* A DEFAULT, NEVER A CONSTANT THE READER GOES LOOKING FOR. Which file holds a project's bars is
|
|
44
|
-
* that project's own fact, and a caller naming its own is answered by that name — this is only
|
|
45
|
-
* what stands in when none is given, and it is exported so a caller happy with the convention does
|
|
46
|
-
* not have to respell it and get one character of it wrong.
|
|
47
|
-
*/
|
|
48
|
-
export const RECORD_FILE = "quality-thresholds.yml";
|
|
49
|
-
/**
|
|
50
|
-
* Reconcile one gate's run against the bar its project's record states.
|
|
51
|
-
*
|
|
52
|
-
* @param request the five terms the calling project owns
|
|
53
|
-
* @returns the verdict, red or green, carrying the line its reader gets
|
|
54
|
-
* @throws MalformedRecordError when the record cannot be read as a bar, or holds no such gate
|
|
55
|
-
*/
|
|
56
|
-
export function reconcileGate(request) {
|
|
57
|
-
const recordFile = request.recordFile ?? RECORD_FILE;
|
|
58
|
-
const records = parseGateRecords(readFileSync(join(request.root, recordFile), "utf8"), recordFile);
|
|
59
|
-
const record = gateRecordFor(request.gate, records, recordFile);
|
|
60
|
-
const read = readMutationReport(request.gate, join(request.root, request.reportPath));
|
|
61
|
-
// A refusal is carried through as the verdict it implies rather than as an absence: a report that
|
|
62
|
-
// is not there is a gate that produced no score, which is not a gate that passed.
|
|
63
|
-
return read.ok
|
|
64
|
-
? verdictFor(record, read.measurement, request.bankCommand)
|
|
65
|
-
: noMeasurement(request.gate, read.reason);
|
|
66
|
-
}
|
|
67
|
-
//# sourceMappingURL=reconcile.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/mutation-ratchet/reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAwB,MAAM,cAAc,CAAC;AAE/E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,wBAAwB,CAAC;AAgCpD;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,OAAuB;IACnD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,WAAW,CAAC;IACrD,MAAM,OAAO,GAAG,gBAAgB,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC;IACnG,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAEtF,kGAAkG;IAClG,kFAAkF;IAClF,OAAO,IAAI,CAAC,EAAE;QACZ,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC;QAC3D,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* THE VERDICT — what a gate's run turned out to be, reconciled against the record it last banked
|
|
3
|
-
* (@SCN-RAT-004, 3F-2794; @SCN-RAT-005, 3F-2795; @SCN-RAT-006, 3F-2796; @SCN-RAT-007, 3F-2797;
|
|
4
|
-
* @SCN-RAT-008, 3F-2798; @SCN-RAT-016, 3F-2809).
|
|
5
|
-
*
|
|
6
|
-
* A BAR CAN ONLY ASK WHETHER ONE NUMBER FELL, AND THE INTERESTING QUESTION IS WHY. A mutation score
|
|
7
|
-
* is detected over total, so it drops for two entirely unrelated reasons: a mutant this suite used
|
|
8
|
-
* to kill now survives, which is the fault the gate exists for; or new mutable code arrived carrying
|
|
9
|
-
* survivors with it, which is no fault at all. `record.ts` keeps the two counts apart so that this
|
|
10
|
-
* module can tell those apart — and telling them apart is the whole product.
|
|
11
|
-
*
|
|
12
|
-
* THE KILLS ARE ASKED ABOUT FIRST, AND ASKED ABOUT ALONE. A run that loses kills WHILE its mutant
|
|
13
|
-
* population grows is the shape every looser reading gets wrong. The growth is a true fact about
|
|
14
|
-
* that run and innocent on its own, so a reconciler that notices it before it counts the kills
|
|
15
|
-
* answers with the innocent half — the score fell, the population explains why, nobody looks any
|
|
16
|
-
* further and a real regression ships. So the count comparison is the first thing this module does,
|
|
17
|
-
* and the population's movement is never allowed to be the answer while a kill is missing.
|
|
18
|
-
*
|
|
19
|
-
* AND INSIDE THAT FIRST COMPARISON, THE POPULATION'S DIRECTION DECIDES WHICH RED IS PRINTED. A
|
|
20
|
-
* population that held still or grew is what licenses the regression's sentence: nothing left the
|
|
21
|
-
* scope, so the kills that vanished were lost. A population that SHRANK removes that licence, and
|
|
22
|
-
* `population-shrank` says so rather than asserting it anyway — removing one killed mutant, and
|
|
23
|
-
* removing one survivor beside a weakened assertion, move the two counts identically, and no
|
|
24
|
-
* arithmetic over two whole numbers tells them apart (@SCN-RAT-016). Both readings are red and
|
|
25
|
-
* both stop the gate; only the sentence differs, and the sentence is the whole point.
|
|
26
|
-
*
|
|
27
|
-
* AND THE SCORE HAS EXACTLY ONE JOB, WHICH IS THE SECOND COMPARISON AND NOT THE FIRST. Once the
|
|
28
|
-
* kills are known to have held, the run either scored below what the record banked or it did not,
|
|
29
|
-
* and only the first of those is a population that grew: a run whose kills ROSE far enough carries
|
|
30
|
-
* its growth without any drop at all, and is an improvement rather than this. So the growth is not
|
|
31
|
-
* what is asked about — the fallen score is, and the growth follows from it, because a run that
|
|
32
|
-
* lost no kills can only score lower by measuring more mutants. That is the whole of what the score
|
|
33
|
-
* is allowed to decide here, and it is why it is asked second (@SCN-RAT-006).
|
|
34
|
-
*
|
|
35
|
-
* THE FLOOR IS STATED, NEVER CONSULTED. `floorOf` is deliberately absent from every condition here.
|
|
36
|
-
* It is the same bar expressed as a percentage, carried in the message because a reader arriving
|
|
37
|
-
* from the sweep has a percentage in front of them and wants the bar in the units they are already
|
|
38
|
-
* holding. The enforcement is the count comparison above it. The two agree exactly while the
|
|
39
|
-
* population holds still and part company the moment it moves, so reading the floor AS the gate
|
|
40
|
-
* would put the judgement back on the score — the confusion the counts model exists to prevent.
|
|
41
|
-
*
|
|
42
|
-
* NOTHING HERE NAMES A PROJECT, A CHECK, A RUNNER, A WORKFLOW OR A REPOSITORY. The gate's name
|
|
43
|
-
* arrives on the record and on the measurement, both of them the caller's own words.
|
|
44
|
-
*/
|
|
45
|
-
import { type GateRecord } from "./record.js";
|
|
46
|
-
/**
|
|
47
|
-
* One gate's measured run, in the same two counts the record is kept in.
|
|
48
|
-
*
|
|
49
|
-
* THE SAME PAIR AS THE RECORD, AND THAT IS WHAT MAKES THE COMPARISON POSSIBLE. A measurement that
|
|
50
|
-
* arrived as a score would already have folded the two events this module exists to separate into
|
|
51
|
-
* one number, before anything here could look at it.
|
|
52
|
-
*/
|
|
53
|
-
export interface MutationMeasurement {
|
|
54
|
-
/** The gate this run measured, as the caller names it. */
|
|
55
|
-
readonly gate: string;
|
|
56
|
-
/** Mutants the suite detected. */
|
|
57
|
-
readonly detected: number;
|
|
58
|
-
/** Every mutant the gate measured, detected or not. */
|
|
59
|
-
readonly total: number;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* What a run turned out to be.
|
|
63
|
-
*
|
|
64
|
-
* `regression` IS THE ONE DECIDED ON KILLS, which is what makes it immune to the population moving,
|
|
65
|
-
* and `within-slack` (@SCN-RAT-005) is its neighbour on the other side of the same comparison — the
|
|
66
|
-
* two share one boundary and neither can pin it alone. `population-grew` (@SCN-RAT-006) is the third
|
|
67
|
-
* built, and the first decided on anything but kills — it is the drop a bar shaped like a score
|
|
68
|
-
* cannot express, and the reason the record keeps two counts rather than one. `unrecorded-improvement`
|
|
69
|
-
* (@SCN-RAT-007) is the fourth, and the only RED one not decided on kills — it is the clause that
|
|
70
|
-
* turns a ceiling into a ratchet, and without it every other arm here is a bar that quietly drifts
|
|
71
|
-
* away from the tree it is meant to be holding. `at-baseline` (@SCN-RAT-008) is the fifth and the
|
|
72
|
-
* one that CLOSES the set: it is what is left once those four have each declined a run, so from it
|
|
73
|
-
* on there is no measurement this module can be handed that it cannot answer. `population-shrank`
|
|
74
|
-
* (@SCN-RAT-016) is the sixth built and `population-grew`'s twin on the other side of the same
|
|
75
|
-
* movement: it shares `regression`'s condition exactly and parts from it on the population's
|
|
76
|
-
* direction alone, because the sentence `regression` is allowed to say is licensed by nothing
|
|
77
|
-
* having left the scope. The last member sits
|
|
78
|
-
* outside the comparison entirely — `no-measurement` (@SCN-RAT-009) is reached from a report that
|
|
79
|
-
* holds nothing, before there are two counts to reconcile at all.
|
|
80
|
-
*/
|
|
81
|
-
export type MutationVerdictKind = "no-measurement" | "regression" | "population-shrank" | "within-slack" | "population-grew" | "unrecorded-improvement" | "at-baseline";
|
|
82
|
-
/**
|
|
83
|
-
* A verdict: whether the run stands, and the line its reader gets.
|
|
84
|
-
*
|
|
85
|
-
* THE MESSAGE IS NOT DECORATION. A verdict that reds without saying which kills went missing, what
|
|
86
|
-
* allowance they were measured against, and what to do next is a red somebody widens the bar to
|
|
87
|
-
* clear, because widening is cheaper than a hunt with no starting point.
|
|
88
|
-
*/
|
|
89
|
-
export interface MutationVerdict {
|
|
90
|
-
readonly kind: MutationVerdictKind;
|
|
91
|
-
/** Whether the run stands. */
|
|
92
|
-
readonly ok: boolean;
|
|
93
|
-
/** The line its reader gets, carrying every figure the verdict was reached from. */
|
|
94
|
-
readonly message: string;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* The refusal, as a verdict (@SCN-RAT-009, 3F-2800).
|
|
98
|
-
*
|
|
99
|
-
* IT SITS OUTSIDE `verdictFor` BECAUSE IT IS REACHED BEFORE THERE ARE COUNTS TO RECONCILE. Every
|
|
100
|
-
* arm of that function compares two pairs of whole numbers; this one is what a caller has instead
|
|
101
|
-
* of a pair, so handing it a fabricated one — a zero, most temptingly — would put a real verdict's
|
|
102
|
-
* name on a run nobody measured.
|
|
103
|
-
*
|
|
104
|
-
* AND IT IS RED. A sweep that did not run produced no evidence about the tree, and a reconciler
|
|
105
|
-
* that shrugs at no evidence reports success for a run that measured nothing: the build green, the
|
|
106
|
-
* report absent, and the two facts never meeting.
|
|
107
|
-
*
|
|
108
|
-
* @param gate the gate that was to have been measured, as the caller names it
|
|
109
|
-
* @param reason why there is no measurement, naming the path it was sought at
|
|
110
|
-
*/
|
|
111
|
-
export declare function noMeasurement(gate: string, reason: string): MutationVerdict;
|
|
112
|
-
/**
|
|
113
|
-
* Reconcile one gate's run against the bar its record states.
|
|
114
|
-
*
|
|
115
|
-
* INSIDE THAT FIRST COMPARISON, `total` DECIDES WHICH RED IS PRINTED, AND IT IS ASKED THERE RATHER
|
|
116
|
-
* THAN BESIDE IT. The kills must already have fallen past the allowance before the population's
|
|
117
|
-
* direction is consulted at all, so a run that lost no kills is not either red however far its
|
|
118
|
-
* population fell, and a run that lost a kill the allowance covers is the pass below whichever way
|
|
119
|
-
* its population moved. What the direction settles is only which sentence a run that has already
|
|
120
|
-
* failed on kills is told: held still or grew licenses `regression`'s claim that a mutant this
|
|
121
|
-
* suite used to kill now survives, because nothing left the scope; SHRANK does not, and
|
|
122
|
-
* `population-shrank` says the two look identical from here instead (@SCN-RAT-016).
|
|
123
|
-
*
|
|
124
|
-
* THE COUNT COMPARISON IS FIRST, AND IT IS ON `detected` ALONE. Everything below it in this
|
|
125
|
-
* reconciler will be a question about the score, and the score cannot separate a lost kill from a
|
|
126
|
-
* grown population — so the one verdict that must not be reachable through the score is settled
|
|
127
|
-
* before the score is consulted at all. A run that loses kills and grows its population at the same
|
|
128
|
-
* time is named as the regression it is, rather than as the growth that would explain it away.
|
|
129
|
-
*
|
|
130
|
-
* `floorOf` IS DELIBERATELY ABSENT FROM THIS CONDITION. It is the same bar as a percentage, carried
|
|
131
|
-
* in the message for its reader; the enforcement is the comparison above. The two agree exactly
|
|
132
|
-
* while the population holds still, so a reconciler judging on the floor greens every example of
|
|
133
|
-
* this Rule and reds a grown population that lost nothing — which is the confusion the counts model
|
|
134
|
-
* exists to prevent.
|
|
135
|
-
*
|
|
136
|
-
* THE SECOND COMPARISON IS THE SAME BOUNDARY FROM THE OTHER SIDE. A run that lost kills the
|
|
137
|
-
* allowance covers is a pass, and `D == D0 - slack` is the last measurement it covers. The two arms
|
|
138
|
-
* meet at that one mutant and neither pins it alone: every run the arm above judges is a regression
|
|
139
|
-
* under `<` and `<=` alike, and under an allowance consulted or forgotten alike. It is the pass at
|
|
140
|
-
* the boundary that reds a comparison widened by one, and the pass one kill inside it that reds a
|
|
141
|
-
* comparison that dropped the allowance — which is why both examples are asserted and not one.
|
|
142
|
-
*
|
|
143
|
-
* THE THIRD COMPARISON IS THE FIRST ONE THE SCORE IS ALLOWED INTO, AND ONLY BECAUSE THE KILLS ARE
|
|
144
|
-
* ALREADY KNOWN TO HAVE HELD. Below this line nothing that used to die is surviving, so a fallen
|
|
145
|
-
* score has exactly one remaining cause — the run measured more mutants — and naming it is safe in
|
|
146
|
-
* a way it was never safe above. The order is the guarantee: the same growth that explains a drop
|
|
147
|
-
* here would have explained away a regression two comparisons ago, which is why it is not consulted
|
|
148
|
-
* until there is no regression left for it to explain away.
|
|
149
|
-
*
|
|
150
|
-
* A RUN THAT LOST A KILL THE ALLOWANCE COVERS **WHILE** ITS POPULATION GREW IS THE ARM ABOVE, NOT
|
|
151
|
-
* THIS ONE, and that is a ruling rather than an accident of ordering (@SCN-RAT-005 surfaced the
|
|
152
|
-
* shape and asserted neither way; ruled on 2026-08-26 under @SCN-RAT-006). Its score can be far
|
|
153
|
-
* below the floor, so the growth is there to be reached for. But this verdict's load-bearing
|
|
154
|
-
* sentence is that no mutant which used to die now survives, and of that run the sentence is false;
|
|
155
|
-
* answering with the growth would print it anyway. The allowance was also SPENT, and an allowance
|
|
156
|
-
* spends in public or it does not spend at all — so the pass that must fire is the one naming the
|
|
157
|
-
* kills lost and the record's own reason for tolerating them. Nothing is lost by the ruling: the
|
|
158
|
-
* growth stays legible in the count pairs that pass already carries.
|
|
159
|
-
*
|
|
160
|
-
* AND THE LAST ARM TAKES NO CONDITION, WHICH IS WHAT MAKES THIS FUNCTION TOTAL (@SCN-RAT-008). The
|
|
161
|
-
* three comparisons above leave exactly one case: kills that held, and a score that neither fell
|
|
162
|
-
* nor rose. `scoreFellFrom` and `scoreRoseFrom` are the same two cross-multiplied products read the
|
|
163
|
-
* two ways round, so between them they claim every inequality and EQUAL is what is left — and equal
|
|
164
|
-
* is a fact about the ratio rather than about the pair, which is why the fall-through is written
|
|
165
|
-
* with no condition at all. Narrowing it to "the same two counts" would leave a run of 4350/4486
|
|
166
|
-
* against a record of 2175/2243 with no verdict, and a reconciler that can be handed a measurement
|
|
167
|
-
* it does not answer is one whose callers must handle a case nobody named. There is no default
|
|
168
|
-
* green here either: `at-baseline` is a verdict somebody wrote, with its own scenario and its own
|
|
169
|
-
* message, not a shrug at the end of a chain of `if`s.
|
|
170
|
-
*
|
|
171
|
-
* @param record the gate's last-banked counts and the allowance stated against them
|
|
172
|
-
* @param measurement the run being judged, in the same two counts
|
|
173
|
-
* @param bankCommand the caller's own words for banking a measurement, carried into the verdicts
|
|
174
|
-
* that ask for it — never a script name this module invents (@SCN-RAT-006, 3F-2796)
|
|
175
|
-
*/
|
|
176
|
-
export declare function verdictFor(record: GateRecord, measurement: MutationMeasurement, bankCommand: string): MutationVerdict;
|
|
177
|
-
//# sourceMappingURL=verdict.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"verdict.d.ts","sourceRoot":"","sources":["../../src/mutation-ratchet/verdict.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EAOL,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAErB;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,mBAAmB,GAC3B,gBAAgB,GAChB,YAAY,GACZ,mBAAmB,GACnB,cAAc,GACd,iBAAiB,GACjB,wBAAwB,GACxB,aAAa,CAAC;AAElB;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,oFAAoF;IACpF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAkQD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,CAW3E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,mBAAmB,EAChC,WAAW,EAAE,MAAM,GAClB,eAAe,CAgBjB"}
|