spec-controller 0.1.0-alpha.3 → 0.1.0-alpha.5
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/dist/cli-args.d.ts +1 -1
- package/dist/cli-args.js +1 -1
- package/dist/cli-balance/cli.d.ts +18 -1
- package/dist/cli-balance/cli.d.ts.map +1 -1
- package/dist/cli-balance/cli.js +159 -149
- package/dist/cli-balance/cli.js.map +1 -1
- package/dist/cli-registry.d.ts.map +1 -1
- package/dist/cli-registry.js +0 -5
- package/dist/cli-registry.js.map +1 -1
- package/dist/corpus/cli.d.ts.map +1 -1
- package/dist/corpus/cli.js +1 -4
- package/dist/corpus/cli.js.map +1 -1
- package/dist/deferralTags.d.ts +2 -2
- package/dist/deferralTags.js +2 -2
- package/dist/ingest/gherkinValidation.d.ts +6 -5
- package/dist/ingest/gherkinValidation.d.ts.map +1 -1
- package/dist/ingest/gherkinValidation.js +6 -5
- package/dist/ingest/gherkinValidation.js.map +1 -1
- package/dist/ingest/ingestQualityChecks.d.ts +0 -25
- package/dist/ingest/ingestQualityChecks.d.ts.map +1 -1
- package/dist/ingest/ingestQualityChecks.js +7 -79
- package/dist/ingest/ingestQualityChecks.js.map +1 -1
- package/package.json +2 -7
- package/dist/mutation-ratchet/index.d.ts +0 -46
- package/dist/mutation-ratchet/index.d.ts.map +0 -1
- package/dist/mutation-ratchet/index.js +0 -46
- package/dist/mutation-ratchet/index.js.map +0 -1
- package/dist/mutation-ratchet/record.d.ts +0 -178
- package/dist/mutation-ratchet/record.d.ts.map +0 -1
- package/dist/mutation-ratchet/record.js +0 -314
- package/dist/mutation-ratchet/record.js.map +0 -1
- package/dist/mutation-ratchet/report.d.ts +0 -109
- package/dist/mutation-ratchet/report.d.ts.map +0 -1
- package/dist/mutation-ratchet/report.js +0 -156
- package/dist/mutation-ratchet/report.js.map +0 -1
|
@@ -23,11 +23,12 @@
|
|
|
23
23
|
* PURE: `string → parse errors`. No fs, no process — the file READ lives beside it at the ingest
|
|
24
24
|
* edge, as it does for every other input.
|
|
25
25
|
*
|
|
26
|
-
* WHY IT LIVES IN THE APP, NOT CORE. Core's barrel is the
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* and the
|
|
26
|
+
* WHY IT LIVES IN THE APP, NOT CORE. Core's barrel is the v1 contract surface downstream consumers
|
|
27
|
+
* build on. Since 3F-3449 nothing reds when a symbol is added there — the guard that reconciled it
|
|
28
|
+
* both directions is gone — so keeping it narrow is a discipline rather than a gate. This validator
|
|
29
|
+
* is an INGEST concern (it decides whether an input can be read at all), not part of the
|
|
30
|
+
* reconciliation contract, so it belongs with the other readers at the app edge and the v1 surface
|
|
31
|
+
* stays untouched.
|
|
31
32
|
*/
|
|
32
33
|
/** A Gherkin parse failure: the file could not be read as Gherkin at all. */
|
|
33
34
|
export interface GherkinParseError {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gherkinValidation.d.ts","sourceRoot":"","sources":["../../src/ingest/gherkinValidation.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"gherkinValidation.d.ts","sourceRoot":"","sources":["../../src/ingest/gherkinValidation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAKH,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAa/E;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,4BAA6B,SAAQ,KAAK;IACrD,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;gBAElC,MAAM,EAAE,SAAS,iBAAiB,EAAE;CAUjD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,8FAA8F;IAC9F,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,SAAS,EAAE,MAAM;CAK9B"}
|
|
@@ -23,11 +23,12 @@
|
|
|
23
23
|
* PURE: `string → parse errors`. No fs, no process — the file READ lives beside it at the ingest
|
|
24
24
|
* edge, as it does for every other input.
|
|
25
25
|
*
|
|
26
|
-
* WHY IT LIVES IN THE APP, NOT CORE. Core's barrel is the
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* and the
|
|
26
|
+
* WHY IT LIVES IN THE APP, NOT CORE. Core's barrel is the v1 contract surface downstream consumers
|
|
27
|
+
* build on. Since 3F-3449 nothing reds when a symbol is added there — the guard that reconciled it
|
|
28
|
+
* both directions is gone — so keeping it narrow is a discipline rather than a gate. This validator
|
|
29
|
+
* is an INGEST concern (it decides whether an input can be read at all), not part of the
|
|
30
|
+
* reconciliation contract, so it belongs with the other readers at the app edge and the v1 surface
|
|
31
|
+
* stays untouched.
|
|
31
32
|
*/
|
|
32
33
|
import { AstBuilder, GherkinClassicTokenMatcher, Parser } from "@cucumber/gherkin";
|
|
33
34
|
import { IdGenerator } from "@cucumber/messages";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gherkinValidation.js","sourceRoot":"","sources":["../../src/ingest/gherkinValidation.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"gherkinValidation.js","sourceRoot":"","sources":["../../src/ingest/gherkinValidation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAUjD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,MAAc;IACxD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,0BAA0B,EAAE,CAAC,CAAC;IAEhG,IAAI,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,0FAA0F;QAC1F,sFAAsF;QACtF,0FAA0F;QAC1F,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IAC5C,MAAM,CAA+B;IAE9C,YAAY,MAAoC;QAC9C,KAAK,CACH;YACE,yEAAyE;YACzE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC;SAC5D,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;QAC3C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD,8FAA8F;IACrF,SAAS,CAAS;IAE3B,YAAY,SAAiB;QAC3B,KAAK,CAAC,gDAAgD,SAAS,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;QACxC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF"}
|
|
@@ -15,25 +15,6 @@
|
|
|
15
15
|
import { type GherkinParseError } from "./gherkinValidation.js";
|
|
16
16
|
import { type EvidenceObligations } from "@3f-consulting/spec-controller-core";
|
|
17
17
|
import type { EvidenceReconciliation } from "@3f-consulting/spec-controller-core";
|
|
18
|
-
/**
|
|
19
|
-
* A reader over ONE resolution pass's records.
|
|
20
|
-
*
|
|
21
|
-
* EACH RECORD IS OPENED ONCE, WHICH IS WHY THIS IS A CLOSURE AND NOT A FUNCTION PER REFERENCE. A
|
|
22
|
-
* manifest may name several gates of one record, and a reader opening it per entry would let two
|
|
23
|
-
* references answer for two different states of the same file — a rewrite landing mid-pass, a gate
|
|
24
|
-
* present for one and gone for the next. One read makes the pass's bars one reading of one record.
|
|
25
|
-
*
|
|
26
|
-
* THE REFUSAL IS REMEMBERED TOO. Cacheing only the successes would re-open an absent or unreadable
|
|
27
|
-
* record per reference, which is the same disagreement by the other door — and the likelier door,
|
|
28
|
-
* since a record being rewritten is unreadable for exactly the window that matters.
|
|
29
|
-
*
|
|
30
|
-
* THE SUBTRACTION IS THE RECORD'S, NOT THIS EDGE'S. `killFloorOf` spends the allowance; an edge
|
|
31
|
-
* computing `detected - slack` itself would be a second place holding a fact about the record.
|
|
32
|
-
*/
|
|
33
|
-
export declare function killFloorReaderFor(root: string): (reference: {
|
|
34
|
-
readonly mutationGate: string;
|
|
35
|
-
readonly recordFile?: string;
|
|
36
|
-
}) => number | null;
|
|
37
18
|
/**
|
|
38
19
|
* The reconciler's resolved input paths — the CLI options threaded to the readers.
|
|
39
20
|
* Every path is optional; a missing result file is tolerated (its evidence is
|
|
@@ -48,12 +29,6 @@ export interface ReconcileOptions {
|
|
|
48
29
|
cucumber?: string;
|
|
49
30
|
ci?: string;
|
|
50
31
|
packageJson?: string;
|
|
51
|
-
/**
|
|
52
|
-
* The measurement artefact (@SCN-CIP-003) — the number each measured check posted, and
|
|
53
|
-
* the credit side of every measured fitness check. Optional like the other result files: absent,
|
|
54
|
-
* it contributes nothing, and each measured obligation it would have answered reads `missing`.
|
|
55
|
-
*/
|
|
56
|
-
measurements?: string;
|
|
57
32
|
/**
|
|
58
33
|
* The CI RUN'S OWN RECORD of what each of its steps did (@SCN-LNT-021, @SCN-LNT-028) — the credit
|
|
59
34
|
* side of every CONVERTED fitness check, written by the consumer's own pipeline and by neither
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingestQualityChecks.d.ts","sourceRoot":"","sources":["../../src/ingest/ingestQualityChecks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAYH,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"ingestQualityChecks.d.ts","sourceRoot":"","sources":["../../src/ingest/ingestQualityChecks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAYH,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,qCAAqC,CAAC;AAkB7C,OAAO,KAAK,EAIV,sBAAsB,EACvB,MAAM,qCAAqC,CAAC;AA6B7C;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA8ED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,iBAAiB,EAAE,CAQ7F;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAStF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAM1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAqB9E;AA0CD,wBAAgB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,sBAAsB,CA2D3E"}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* `package.json` to observe each fitness check the corpus cites.
|
|
14
14
|
*/
|
|
15
15
|
import { readFileSync, existsSync } from "node:fs";
|
|
16
|
-
import { basename
|
|
16
|
+
import { basename } from "node:path";
|
|
17
17
|
import { ciSourcePathsOf } from "./ciSourcePaths.js";
|
|
18
18
|
import { discoverFeatures } from "./ingestScenarios.js";
|
|
19
19
|
import { parseScenarios, countScnOccurrences, parseUntaggedScenarios, proseOnlyCodes, } from "@3f-consulting/spec-controller-core";
|
|
@@ -30,12 +30,6 @@ import { parseCucumberEvidenceObservations, } from "@3f-consulting/spec-controll
|
|
|
30
30
|
// their CALLER. What is left here is the reads: this edge opens the files and hands the bytes over.
|
|
31
31
|
import { evidenceReconciliationFromSources } from "@3f-consulting/spec-controller-core";
|
|
32
32
|
import { resolveTargetRoot } from "../run-management/resolveRunInputs.js";
|
|
33
|
-
// The record reader, reached for the RECORD half of a bar that names a gate (@SCN-MUT-012): its
|
|
34
|
-
// conventional record name, its parser, and the floor a gate's own figures imply. Through the
|
|
35
|
-
// barrel, which is the surface a caller holds. (The directory is still spelled `mutation-ratchet`
|
|
36
|
-
// and the ratchet it was named for is deleted — 3F-3337 left the name standing rather than move a
|
|
37
|
-
// module inside a delete; filed as a finding.)
|
|
38
|
-
import { gateRecordFor, killFloorOf, MalformedRecordError, parseGateRecords, RECORD_FILE, } from "../mutation-ratchet/index.js";
|
|
39
33
|
/**
|
|
40
34
|
* The per-input FALLBACK quality-check for each JS-ecosystem result source — the
|
|
41
35
|
* source→quality-check mapping, SET at the CLI edge rather than hardcoded in the core
|
|
@@ -61,67 +55,6 @@ const CUCUMBER_QUALITY_CHECK = "integration";
|
|
|
61
55
|
* (`parse/commandRuns`), so this names the reconciliation and nothing else the tool can do.
|
|
62
56
|
*/
|
|
63
57
|
const RECONCILER_INVOCATION = "spec-controller balance";
|
|
64
|
-
/**
|
|
65
|
-
* A refusal met with an absent bar rather than let out of this edge.
|
|
66
|
-
*
|
|
67
|
-
* NOTHING IS THROWN OUT OF HERE, and that is the stance rather than caution. A refusal that escapes
|
|
68
|
-
* costs the whole run its verdict over one bad character in a file nobody may even be reading — a
|
|
69
|
-
* fault that is loud nowhere, where an absent bar is loud on the ledger. It is `thresholdsOf`'s own
|
|
70
|
-
* stance for a malformed entry, applied to the half of a bar that now lives in a second file.
|
|
71
|
-
*
|
|
72
|
-
* TWO CLASSES AND NO MORE. The record library normalises every fault it can see — the YAML parser's
|
|
73
|
-
* own included — into `MalformedRecordError` precisely so a caller catches all of them by catching
|
|
74
|
-
* one; beside it sits the read that never got as far as a record. A bare catch would swallow a
|
|
75
|
-
* defect in this edge as well, and answer it with the same silent absence.
|
|
76
|
-
*/
|
|
77
|
-
function orNoBar(read) {
|
|
78
|
-
try {
|
|
79
|
-
return read();
|
|
80
|
-
}
|
|
81
|
-
catch (cause) {
|
|
82
|
-
if (cause instanceof MalformedRecordError || isReadRefusal(cause))
|
|
83
|
-
return null;
|
|
84
|
-
throw cause;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
/** A filesystem refusal — the record was not there, or could not be opened. */
|
|
88
|
-
function isReadRefusal(cause) {
|
|
89
|
-
return cause instanceof Error && typeof cause.code === "string";
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* A reader over ONE resolution pass's records.
|
|
93
|
-
*
|
|
94
|
-
* EACH RECORD IS OPENED ONCE, WHICH IS WHY THIS IS A CLOSURE AND NOT A FUNCTION PER REFERENCE. A
|
|
95
|
-
* manifest may name several gates of one record, and a reader opening it per entry would let two
|
|
96
|
-
* references answer for two different states of the same file — a rewrite landing mid-pass, a gate
|
|
97
|
-
* present for one and gone for the next. One read makes the pass's bars one reading of one record.
|
|
98
|
-
*
|
|
99
|
-
* THE REFUSAL IS REMEMBERED TOO. Cacheing only the successes would re-open an absent or unreadable
|
|
100
|
-
* record per reference, which is the same disagreement by the other door — and the likelier door,
|
|
101
|
-
* since a record being rewritten is unreadable for exactly the window that matters.
|
|
102
|
-
*
|
|
103
|
-
* THE SUBTRACTION IS THE RECORD'S, NOT THIS EDGE'S. `killFloorOf` spends the allowance; an edge
|
|
104
|
-
* computing `detected - slack` itself would be a second place holding a fact about the record.
|
|
105
|
-
*/
|
|
106
|
-
export function killFloorReaderFor(root
|
|
107
|
-
// The reader's shape is SPELLED here rather than imported, and that is the boundary working
|
|
108
|
-
// rather than a duplication. `KillFloorReader` and the reference it takes are core-internal —
|
|
109
|
-
// the registry-home question (increment D) still governs them — and this module is published, so
|
|
110
|
-
// naming them by their `./internal` types would put an unpublished specifier back in the tarball
|
|
111
|
-
// for a type alone. Structural typing is what makes the closure the engine's parameter accepts.
|
|
112
|
-
) {
|
|
113
|
-
const opened = new Map();
|
|
114
|
-
return (reference) => {
|
|
115
|
-
const recordFile = reference.recordFile ?? RECORD_FILE;
|
|
116
|
-
if (!opened.has(recordFile)) {
|
|
117
|
-
opened.set(recordFile, orNoBar(() => parseGateRecords(readFileSync(join(root, recordFile), "utf8"), recordFile)));
|
|
118
|
-
}
|
|
119
|
-
const records = opened.get(recordFile);
|
|
120
|
-
if (records == null)
|
|
121
|
-
return null;
|
|
122
|
-
return orNoBar(() => killFloorOf(gateRecordFor(reference.mutationGate, records, recordFile)));
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
58
|
/** Read + JSON-parse a file if present, else return undefined. */
|
|
126
59
|
function readJsonIfPresent(path) {
|
|
127
60
|
if (!path || !existsSync(path))
|
|
@@ -323,9 +256,8 @@ export function runReconcile(opts) {
|
|
|
323
256
|
const pkgPath = opts.packageJson ?? "package.json";
|
|
324
257
|
const packageJson = readJsonIfPresent(pkgPath) ?? {};
|
|
325
258
|
// The TARGET repo root — the credit locators are made relative to it, so a phantom-scenario row's
|
|
326
|
-
// where-to-fix (ruling Q5) stays portable in a banked artefact
|
|
327
|
-
//
|
|
328
|
-
// threaded, which is also what keeps `execFileSync` and `process.cwd()` out of the engine.
|
|
259
|
+
// where-to-fix (ruling Q5) stays portable in a banked artefact. Resolved ONCE here and threaded,
|
|
260
|
+
// which is also what keeps `execFileSync` and `process.cwd()` out of the engine.
|
|
329
261
|
const root = resolveTargetRoot({ features: opts.features });
|
|
330
262
|
// `--ci` names a workflow FILE or a DIRECTORY of them, and defaults to the directory
|
|
331
263
|
// (@SCN-USG-006, 3F-2238): a pipeline split across files enforces its checks just as one
|
|
@@ -355,26 +287,22 @@ export function runReconcile(opts) {
|
|
|
355
287
|
// half of the entry that does not come out of the workflow's own text. The directory it sits
|
|
356
288
|
// in is the caller's `--ci`, not the consumer's subject, so it is not part of what they write.
|
|
357
289
|
ciSourceNames: ciPaths.map((path) => basename(path)),
|
|
358
|
-
measurements: readJsonIfPresent(opts.measurements) ?? {},
|
|
359
290
|
// The CONVERTED checks' credit stream, read at this edge like every other report. Absent it is
|
|
360
291
|
// undefined rather than empty, and that distinction reaches the reader (@SCN-LNT-027): "no
|
|
361
292
|
// record" is a run nobody recorded, "a record holding nothing" is a run that recorded none of
|
|
362
293
|
// these steps, and those are opposite facts.
|
|
363
|
-
// STRUCTURALLY, NOT BY NAME
|
|
364
|
-
// travels in the tarball and reaches core through the PUBLIC barrel alone (3F-3086), and
|
|
294
|
+
// STRUCTURALLY, NOT BY NAME: this module travels in the tarball and reaches core through the PUBLIC barrel alone (3F-3086), and
|
|
365
295
|
// `CiStepRecord` is not on it. The shape is the document's, which is the consumer's, so what is
|
|
366
296
|
// written here is what the file holds rather than a contract owed to anyone.
|
|
367
297
|
ciStepRecord: readJsonIfPresent(opts.ciSteps),
|
|
368
298
|
runtimeObservations: parseRuntimeObservations(opts, root),
|
|
369
|
-
// The
|
|
370
|
-
// starter deferral set is the application layer's own policy, how this tool is invoked to
|
|
371
|
-
// reconcile is a fact about this product's command line
|
|
372
|
-
// target's tree. THE PREFIX SET USED TO SIT HERE AND IS GONE (@SCN-USG-004, 3F-3343): the
|
|
299
|
+
// The two things the engine's resolvers cannot hold, and each for its own reason: the
|
|
300
|
+
// starter deferral set is the application layer's own policy, and how this tool is invoked to
|
|
301
|
+
// reconcile is a fact about this product's command line. THE PREFIX SET USED TO SIT HERE AND IS GONE (@SCN-USG-004, 3F-3343): the
|
|
373
302
|
// engine no longer decides a check's membership by its name, so there is no convention left
|
|
374
303
|
// for this edge to own.
|
|
375
304
|
deferralTags: DEFAULT_DEFERRAL_TAGS,
|
|
376
305
|
reconcilerInvocation: RECONCILER_INVOCATION,
|
|
377
|
-
killFloor: killFloorReaderFor(root),
|
|
378
306
|
});
|
|
379
307
|
}
|
|
380
308
|
// The static-check kind-counts are no longer read as a parallel census (@SCN-USG-001 / 3F-2118):
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingestQualityChecks.js","sourceRoot":"","sources":["../../src/ingest/ingestQualityChecks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"ingestQualityChecks.js","sourceRoot":"","sources":["../../src/ingest/ingestQualityChecks.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spec-controller",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.5",
|
|
4
4
|
"description": "Reconcile the behaviour your scenarios name against the evidence that actually ran — the deterministic `balance` CLI.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"reconciliation",
|
|
@@ -10,11 +10,6 @@
|
|
|
10
10
|
"double-entry",
|
|
11
11
|
"cli"
|
|
12
12
|
],
|
|
13
|
-
"repository": {
|
|
14
|
-
"type": "git",
|
|
15
|
-
"url": "git+https://github.com/3f-consulting/spec-controller.git",
|
|
16
|
-
"directory": "packages/spec-controller"
|
|
17
|
-
},
|
|
18
13
|
"license": "MIT",
|
|
19
14
|
"type": "module",
|
|
20
15
|
"engines": {
|
|
@@ -30,7 +25,7 @@
|
|
|
30
25
|
"@cucumber/gherkin": "^41.0.0",
|
|
31
26
|
"@cucumber/messages": "^34.0.1",
|
|
32
27
|
"yaml": "^2.9.0",
|
|
33
|
-
"@3f-consulting/spec-controller-core": "0.1.0-alpha.
|
|
28
|
+
"@3f-consulting/spec-controller-core": "0.1.0-alpha.5"
|
|
34
29
|
},
|
|
35
30
|
"publishConfig": {
|
|
36
31
|
"access": "public"
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* THE MODULE'S OWN SURFACE — curated symbol by symbol, never a re-export of the tree behind it
|
|
3
|
-
* (3F-2804, 3F-3337).
|
|
4
|
-
*
|
|
5
|
-
* WHAT IS BEHIND THIS BARREL NOW IS TWO READERS, AND THE RATCHET THEY WERE BUILT FOR IS GONE
|
|
6
|
-
* (3F-3337). `record.ts` reads a target's banked gate record and hands back the kill floor it
|
|
7
|
-
* implies; `report.ts` counts a mutation report's own mutants into a measurement. What left with
|
|
8
|
-
* the ratchet is everything that COMPARED the two — the verdicts, the up-only recorder, the
|
|
9
|
-
* reconciliation entry and the command that ended on it — because this repository's gate is now a
|
|
10
|
-
* per-mutant comparison the runner keeps, and nothing types a mutation count here any more.
|
|
11
|
-
*
|
|
12
|
-
* ITS TWO CONSUMERS ARE BOTH IN THIS TREE, AND THEY WANT DIFFERENT HALVES. `ingest/
|
|
13
|
-
* ingestQualityChecks.ts` wants the RECORD half: the engine's `mutationGate` bar kind lets a target
|
|
14
|
-
* author a fitness row naming a gate instead of a figure, which is a published capability decided
|
|
15
|
-
* over a target's own record (@SCN-MUT-012, @SCN-MUT-013). `tests/checks/mutationScoreCli.ts` wants
|
|
16
|
-
* the REPORT half: `pnpm mutation:score` takes the two counts out of a sweep's report and divides
|
|
17
|
-
* them (@SCN-MUT-007, @SCN-MUT-008). Neither wants the other's, which is why both are named here
|
|
18
|
-
* rather than the tree behind them being passed on wholesale.
|
|
19
|
-
*
|
|
20
|
-
* A BARREL THAT RE-EXPORTED EVERY MODULE WOULD BE A CONTRACT NOBODY WROTE. Each module below
|
|
21
|
-
* exports what its own siblings need from it, and sibling-visibility is a much wider set than
|
|
22
|
-
* consumer-visibility. Passing that set on wholesale would freeze every one of them as something a
|
|
23
|
-
* caller may depend on, and the first refactor that moved one would be a breaking change nobody
|
|
24
|
-
* meant to make. So this file names what a caller may hold and the omissions are decisions.
|
|
25
|
-
*
|
|
26
|
-
* THE KILL FLOOR IS THE BAR, AND IT IS NOT A SCORE (3F-2788). `killFloorOf` answers a ledger
|
|
27
|
-
* holding a measured row to the figure a gate's own record implies, in mutants — a percentage would
|
|
28
|
-
* fold the kill lost and the population grown into one number, which is the distinction a bar on
|
|
29
|
-
* this axis exists to keep. A consumer that derived it instead would be the second place knowing
|
|
30
|
-
* how an allowance is spent.
|
|
31
|
-
*
|
|
32
|
-
* THE TYPES ARE SPELLED FOR A CONSUMER'S NAMESPACE RATHER THAN FOR THIS MODULE'S. `GateRecord` is
|
|
33
|
-
* unambiguous inside a directory about nothing else; imported into a repository that has gates of
|
|
34
|
-
* several kinds it is not, so it crosses this line under the fuller name. The aliasing is
|
|
35
|
-
* deliberate and one-directional: the internal spelling stays internal.
|
|
36
|
-
*
|
|
37
|
-
* AND NO DRIFT GUARD STANDS OVER IT, WHICH IS A DECISION RATHER THAN AN OPEN QUESTION. The sibling
|
|
38
|
-
* core package's barrel is reflected and compared against a frozen list in both directions, so a
|
|
39
|
-
* symbol quietly added or dropped reds. That is what a PUBLISHED surface is owed, and 3F-2859
|
|
40
|
-
* stopped publishing this one: no manifest key resolves here, and no caller outside this repository
|
|
41
|
-
* can spell the specifier at all. Freezing the list would make every refactor behind this barrel a
|
|
42
|
-
* change to a contract nobody holds.
|
|
43
|
-
*/
|
|
44
|
-
export { floorOf, gateRecordFor, killFloorOf, MalformedRecordError, parseGateRecords, RECORD_FILE, type GateRecord as MutationGateRecord, } from "./record.js";
|
|
45
|
-
export { measurementFromReport, readMutationReport, type MutationMeasurement, type MutationReportRead, } from "./report.js";
|
|
46
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mutation-ratchet/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EACL,OAAO,EACP,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,KAAK,UAAU,IAAI,kBAAkB,GACtC,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC"}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* THE MODULE'S OWN SURFACE — curated symbol by symbol, never a re-export of the tree behind it
|
|
3
|
-
* (3F-2804, 3F-3337).
|
|
4
|
-
*
|
|
5
|
-
* WHAT IS BEHIND THIS BARREL NOW IS TWO READERS, AND THE RATCHET THEY WERE BUILT FOR IS GONE
|
|
6
|
-
* (3F-3337). `record.ts` reads a target's banked gate record and hands back the kill floor it
|
|
7
|
-
* implies; `report.ts` counts a mutation report's own mutants into a measurement. What left with
|
|
8
|
-
* the ratchet is everything that COMPARED the two — the verdicts, the up-only recorder, the
|
|
9
|
-
* reconciliation entry and the command that ended on it — because this repository's gate is now a
|
|
10
|
-
* per-mutant comparison the runner keeps, and nothing types a mutation count here any more.
|
|
11
|
-
*
|
|
12
|
-
* ITS TWO CONSUMERS ARE BOTH IN THIS TREE, AND THEY WANT DIFFERENT HALVES. `ingest/
|
|
13
|
-
* ingestQualityChecks.ts` wants the RECORD half: the engine's `mutationGate` bar kind lets a target
|
|
14
|
-
* author a fitness row naming a gate instead of a figure, which is a published capability decided
|
|
15
|
-
* over a target's own record (@SCN-MUT-012, @SCN-MUT-013). `tests/checks/mutationScoreCli.ts` wants
|
|
16
|
-
* the REPORT half: `pnpm mutation:score` takes the two counts out of a sweep's report and divides
|
|
17
|
-
* them (@SCN-MUT-007, @SCN-MUT-008). Neither wants the other's, which is why both are named here
|
|
18
|
-
* rather than the tree behind them being passed on wholesale.
|
|
19
|
-
*
|
|
20
|
-
* A BARREL THAT RE-EXPORTED EVERY MODULE WOULD BE A CONTRACT NOBODY WROTE. Each module below
|
|
21
|
-
* exports what its own siblings need from it, and sibling-visibility is a much wider set than
|
|
22
|
-
* consumer-visibility. Passing that set on wholesale would freeze every one of them as something a
|
|
23
|
-
* caller may depend on, and the first refactor that moved one would be a breaking change nobody
|
|
24
|
-
* meant to make. So this file names what a caller may hold and the omissions are decisions.
|
|
25
|
-
*
|
|
26
|
-
* THE KILL FLOOR IS THE BAR, AND IT IS NOT A SCORE (3F-2788). `killFloorOf` answers a ledger
|
|
27
|
-
* holding a measured row to the figure a gate's own record implies, in mutants — a percentage would
|
|
28
|
-
* fold the kill lost and the population grown into one number, which is the distinction a bar on
|
|
29
|
-
* this axis exists to keep. A consumer that derived it instead would be the second place knowing
|
|
30
|
-
* how an allowance is spent.
|
|
31
|
-
*
|
|
32
|
-
* THE TYPES ARE SPELLED FOR A CONSUMER'S NAMESPACE RATHER THAN FOR THIS MODULE'S. `GateRecord` is
|
|
33
|
-
* unambiguous inside a directory about nothing else; imported into a repository that has gates of
|
|
34
|
-
* several kinds it is not, so it crosses this line under the fuller name. The aliasing is
|
|
35
|
-
* deliberate and one-directional: the internal spelling stays internal.
|
|
36
|
-
*
|
|
37
|
-
* AND NO DRIFT GUARD STANDS OVER IT, WHICH IS A DECISION RATHER THAN AN OPEN QUESTION. The sibling
|
|
38
|
-
* core package's barrel is reflected and compared against a frozen list in both directions, so a
|
|
39
|
-
* symbol quietly added or dropped reds. That is what a PUBLISHED surface is owed, and 3F-2859
|
|
40
|
-
* stopped publishing this one: no manifest key resolves here, and no caller outside this repository
|
|
41
|
-
* can spell the specifier at all. Freezing the list would make every refactor behind this barrel a
|
|
42
|
-
* change to a contract nobody holds.
|
|
43
|
-
*/
|
|
44
|
-
export { floorOf, gateRecordFor, killFloorOf, MalformedRecordError, parseGateRecords, RECORD_FILE, } from "./record.js";
|
|
45
|
-
export { measurementFromReport, readMutationReport, } from "./report.js";
|
|
46
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mutation-ratchet/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EACL,OAAO,EACP,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,GAEZ,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,qBAAqB,EACrB,kBAAkB,GAGnB,MAAM,aAAa,CAAC"}
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A GATE'S RECORD — the pair of counts it last banked, and the allowance stated against them
|
|
3
|
-
* (@SCN-MUT-012, 3F-2790, 3F-3337).
|
|
4
|
-
*
|
|
5
|
-
* THE RATCHET THAT ONCE RECONCILED AGAINST THIS IS GONE; THE READER IS NOT (3F-3337). What reaches
|
|
6
|
-
* this module now is the engine's `mutationGate` bar kind, through `ingestQualityChecks.ts`: a
|
|
7
|
-
* target may author a fitness row whose bar names a gate rather than a figure, and the kill floor
|
|
8
|
-
* that gate's record implies is the bar the ledger then holds it to. That is a published
|
|
9
|
-
* capability, decided over a TARGET'S record, and this repository no longer keeps one of its own.
|
|
10
|
-
* @SCN-MUT-012 and @SCN-MUT-013 are what specify it — the second carrying, as its own Examples,
|
|
11
|
-
* the record that holds no gate of that name, the record that is not there to be read and the
|
|
12
|
-
* record holding text nothing can read as a record.
|
|
13
|
-
*
|
|
14
|
-
* THE RECORD IS TWO COUNTS, NEVER A BARE SCORE, and that is the load-bearing choice this whole
|
|
15
|
-
* module exists to make possible. A mutation score is detected over total, so it falls for two
|
|
16
|
-
* entirely unrelated reasons: a mutant this suite used to kill now survives, which is the fault
|
|
17
|
-
* the gate exists for; or new mutable code arrived carrying survivors with it, which is no fault
|
|
18
|
-
* at all. One number reds on both, and the only cheap way out of a red for the second is to widen
|
|
19
|
-
* the bar — which is how a floor loses its teeth. Keeping `detected` and `total` apart is what
|
|
20
|
-
* lets the verdict tell them apart: kills lost is stated directly, and a growing population moves
|
|
21
|
-
* `total` while leaving `detected` alone.
|
|
22
|
-
*
|
|
23
|
-
* NOTHING HERE NAMES A PROJECT, A CHECK, A RUNNER, A WORKFLOW OR A REPOSITORY. The record's text
|
|
24
|
-
* arrives as a string and the name it is filed under arrives beside it, because which file holds a
|
|
25
|
-
* project's bars, and what its gates are called, are that project's own facts. This module has an
|
|
26
|
-
* opinion about the SHAPE of a record and none about whose it is.
|
|
27
|
-
*
|
|
28
|
-
* MALFORMED MEANS NO BAR, NEVER A DEFAULTED ONE. Every refusal below is a record a lenient reader
|
|
29
|
-
* answers with a bar nobody wrote — an absent section read as "no gates to enforce", a gate that
|
|
30
|
-
* measured nothing read as scoring zero, an allowance nobody justified read as justified. The bar
|
|
31
|
-
* is then enforced as though somebody had written it, and the only symptom is a build that has
|
|
32
|
-
* quietly stopped being able to red. So each one is refused by name, and the refusal says which
|
|
33
|
-
* record it read and where in that record the fault is (@SCN-MUT-013, 3F-2792).
|
|
34
|
-
*
|
|
35
|
-
* IT IS NOT A STATIC CHECK, and takes no `static-check:` prefix. A static check is a pure function
|
|
36
|
-
* of the checked-out tree; the record this reads feeds a reconciler that judges a MEASUREMENT,
|
|
37
|
-
* which by construction is not in the tree — the standing ruling every scheduled-sweep reader in
|
|
38
|
-
* this portfolio already carries.
|
|
39
|
-
*/
|
|
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
|
-
* IT MOVED HERE FROM `reconcile.ts` WHEN THE RATCHET LEFT (3F-3337), unchanged. The entry that used
|
|
49
|
-
* to sit beside it reconciled a gate against this record; what is left reading a record is this
|
|
50
|
-
* module, so the default name sits with the reader that defaults to it.
|
|
51
|
-
*/
|
|
52
|
-
export declare const RECORD_FILE = "quality-thresholds.yml";
|
|
53
|
-
/**
|
|
54
|
-
* Raised when a record cannot be read as a bar.
|
|
55
|
-
*
|
|
56
|
-
* IT NAMES THE SECTION, THE GATE AND THE FIELD, because a record file is a wall of near-identical
|
|
57
|
-
* gate blocks and a bare "invalid config" over one of them leaves a reader opening the file and
|
|
58
|
-
* reading every block to find out which. The four together are enough to put a cursor on the line.
|
|
59
|
-
*
|
|
60
|
-
* ONE TYPE FOR EVERY FAULT, INCLUDING THE ONES THIS MODULE DOES NOT DETECT ITSELF. A caller is
|
|
61
|
-
* told to catch this and nothing else, so anything it does not cover is something that caller
|
|
62
|
-
* sails past — which is why the YAML parser's own errors are normalised into it rather than left
|
|
63
|
-
* to travel under their own name. That is what makes "a malformed record fails loudly" a property
|
|
64
|
-
* of the reader rather than a property of the field checks alone.
|
|
65
|
-
*/
|
|
66
|
-
export declare class MalformedRecordError extends Error {
|
|
67
|
-
/** The name the record was filed under, as the caller handed it over. */
|
|
68
|
-
readonly recordFile: string;
|
|
69
|
-
/** The section the fault sits in, or `<document>` when it sits above every section. */
|
|
70
|
-
readonly section: string;
|
|
71
|
-
/** The gate the fault sits under, or a placeholder when the fault is the section itself. */
|
|
72
|
-
readonly key: string;
|
|
73
|
-
/** The field the fault sits at. */
|
|
74
|
-
readonly field: string;
|
|
75
|
-
constructor(
|
|
76
|
-
/** The name the record was filed under, as the caller handed it over. */
|
|
77
|
-
recordFile: string,
|
|
78
|
-
/** The section the fault sits in, or `<document>` when it sits above every section. */
|
|
79
|
-
section: string,
|
|
80
|
-
/** The gate the fault sits under, or a placeholder when the fault is the section itself. */
|
|
81
|
-
key: string,
|
|
82
|
-
/** The field the fault sits at. */
|
|
83
|
-
field: string, detail: string);
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* The allowance a record STATES against a gate's counts — how many kills may be lost before the
|
|
87
|
-
* gate reds, and why that many.
|
|
88
|
-
*
|
|
89
|
-
* COUNTED IN MUTANTS, WITH ITS REASON, and the unit is the point. A mutant is the unit the fault
|
|
90
|
-
* arrives in, so the arithmetic downstream is exact rather than a rounding argument; and a
|
|
91
|
-
* non-zero allowance that cannot say why it exists is head-room rather than tolerance, which is
|
|
92
|
-
* why the reason travels with the number rather than in a comment beside it.
|
|
93
|
-
*/
|
|
94
|
-
export interface GateAllowance {
|
|
95
|
-
/** Whole mutants of tolerance. Zero seats the floor exactly on the record. */
|
|
96
|
-
readonly mutants: number;
|
|
97
|
-
/** Why the allowance exists. */
|
|
98
|
-
readonly reason: string;
|
|
99
|
-
}
|
|
100
|
-
/** One gate's last-banked measurement, and the allowance stated against it. */
|
|
101
|
-
export interface GateRecord {
|
|
102
|
-
/** The gate's name, as the record files it — the project's own word, never this module's. */
|
|
103
|
-
readonly gate: string;
|
|
104
|
-
/** Mutants the suite detected. */
|
|
105
|
-
readonly detected: number;
|
|
106
|
-
/** Every mutant the gate measured, detected or not. */
|
|
107
|
-
readonly total: number;
|
|
108
|
-
readonly allowance: GateAllowance;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* The failing floor: the record's counts with its allowance spent out of the DETECTED count.
|
|
112
|
-
*
|
|
113
|
-
* SPENT FROM THE NUMERATOR, not subtracted from the score, because the allowance is counted in
|
|
114
|
-
* mutants and a mutant is worth a different number of points in every gate — the same allowance
|
|
115
|
-
* taken off two scores would mean two different things in two gates of different sizes.
|
|
116
|
-
*
|
|
117
|
-
* A REPORTED FIGURE, NOT THE DECISION VARIABLE. The verdict decides on COUNTS — fewer kills than
|
|
118
|
-
* the record less its allowance — and prints this floor beside it so a reader has the bar in the
|
|
119
|
-
* units the sweep speaks. The two agree exactly while the mutant population is unchanged, and part
|
|
120
|
-
* company the moment it moves: a grown population drags the measured score below this floor with
|
|
121
|
-
* no kill lost at all, and that case is green. Reading this floor AS the gate would put the
|
|
122
|
-
* judgement back on the score, which is the confusion the counts model exists to prevent.
|
|
123
|
-
*/
|
|
124
|
-
export declare function floorOf(record: GateRecord): number;
|
|
125
|
-
/**
|
|
126
|
-
* The failing floor in MUTANTS: the record's kills with its allowance spent out of them.
|
|
127
|
-
*
|
|
128
|
-
* `floorOf`'s TWIN WITHOUT THE DIVISION, and the division is the whole difference. A percentage is
|
|
129
|
-
* two facts folded into one, and folding them is what makes a floor fall when new mutable code
|
|
130
|
-
* arrives carrying survivors — no kill lost, and the bar missed anyway. Subtracting the allowance
|
|
131
|
-
* and stopping leaves a whole number of mutants that moves only when a mutant this suite used to
|
|
132
|
-
* kill stops dying, which is the one fact a bar on this axis is about.
|
|
133
|
-
*
|
|
134
|
-
* `total` NEVER ENTERS IT, and that is the population-independence rather than a simplification.
|
|
135
|
-
* A reader holding this number can be handed a run over any population at all and still be asking
|
|
136
|
-
* the only question worth asking of it.
|
|
137
|
-
*
|
|
138
|
-
* HERE RATHER THAN AT ITS CALLER, for the reason `floorOf` is here: how an allowance is spent is a
|
|
139
|
-
* fact about the record, and a caller computing `detected - slack` itself would be a second place
|
|
140
|
-
* holding it — agreeing until the day one of them is edited.
|
|
141
|
-
*/
|
|
142
|
-
export declare function killFloorOf(record: GateRecord): number;
|
|
143
|
-
/**
|
|
144
|
-
* Read every gate's record out of a record file's text.
|
|
145
|
-
*
|
|
146
|
-
* @param text the record file's own bytes, as authored
|
|
147
|
-
* @param recordFile the name the record is filed under, so a refusal can say which file it read
|
|
148
|
-
* @throws MalformedRecordError when the text cannot be read as a bar — one type for every fault,
|
|
149
|
-
* the YAML parser's own included, so a caller told to catch this catches all of them.
|
|
150
|
-
*/
|
|
151
|
-
export declare function parseGateRecords(text: string, recordFile: string): Map<string, GateRecord>;
|
|
152
|
-
/**
|
|
153
|
-
* The bar the record holds for one named gate, refused when the record holds no such gate.
|
|
154
|
-
*
|
|
155
|
-
* A GATE WITH NO RECORD IS THE ONE FAULT IN THIS MODULE THAT LOOKS LIKE NOTHING AT ALL. Every
|
|
156
|
-
* refusal above is a record somebody wrote badly, sitting in the file a reader would go and open.
|
|
157
|
-
* This one is a record that reads perfectly, asked for a gate it never held — a gate name mistyped
|
|
158
|
-
* where the caller states it. The lenient answer is not a wrong bar but NO bar, which reads
|
|
159
|
-
* downstream as a gate with nothing to enforce, and it greens for as long as the typo survives.
|
|
160
|
-
* Nothing about the record is wrong, so nobody is ever sent to look at it (@SCN-MUT-013, 3F-2793).
|
|
161
|
-
*
|
|
162
|
-
* AND THE REFUSAL LISTS THE GATES THE RECORD DOES HOLD. A record's gates are near-neighbours by
|
|
163
|
-
* construction — a project names them after the scopes it is quarantining from each other — so a
|
|
164
|
-
* refusal naming only the gate that was asked for sends its reader to open the file and compare
|
|
165
|
-
* spellings by eye. Listing what is held turns the typo into a one-line diagnosis.
|
|
166
|
-
*
|
|
167
|
-
* UNDER THE ONE REFUSAL TYPE, like every fault above it. A caller is told to catch
|
|
168
|
-
* `MalformedRecordError` and nothing else, so an unrecorded gate raised under a second type is a
|
|
169
|
-
* fault that caller sails straight past — the very hole the YAML parser's own errors are
|
|
170
|
-
* normalised to close.
|
|
171
|
-
*
|
|
172
|
-
* @param gate the gate to resolve, as the caller names it — never a name this module knows
|
|
173
|
-
* @param records every gate the record holds, as `parseGateRecords` read them
|
|
174
|
-
* @param recordFile the name the record is filed under, so a refusal can say which file it read
|
|
175
|
-
* @throws MalformedRecordError when the record holds no such gate, listing the gates it does hold
|
|
176
|
-
*/
|
|
177
|
-
export declare function gateRecordFor(gate: string, records: Map<string, GateRecord>, recordFile: string): GateRecord;
|
|
178
|
-
//# sourceMappingURL=record.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../src/mutation-ratchet/record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAIH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,2BAA2B,CAAC;AA0CpD;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAE3C,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM;IAC3B,uFAAuF;IACvF,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,4FAA4F;IAC5F,QAAQ,CAAC,GAAG,EAAE,MAAM;IACpB,mCAAmC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM;;IAPtB,yEAAyE;IAChE,UAAU,EAAE,MAAM;IAC3B,uFAAuF;IAC9E,OAAO,EAAE,MAAM;IACxB,4FAA4F;IACnF,GAAG,EAAE,MAAM;IACpB,mCAAmC;IAC1B,KAAK,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM;CAKjB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,gCAAgC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,+EAA+E;AAC/E,MAAM,WAAW,UAAU;IACzB,6FAA6F;IAC7F,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;CACnC;AAOD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAElD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAEtD;AAiLD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAI1F;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAChC,UAAU,EAAE,MAAM,GACjB,UAAU,CAYZ"}
|