@dzhechkov/harness-core 0.4.4 → 0.5.0
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/.dz-manifest.json +283 -103
- package/LICENSE +21 -0
- package/README.md +73 -5
- package/dist/agents-policy.d.ts +67 -0
- package/dist/agents-policy.d.ts.map +1 -0
- package/dist/agents-policy.js +258 -0
- package/dist/agents-policy.js.map +1 -0
- package/dist/codex-hooks-assets.d.ts +47 -0
- package/dist/codex-hooks-assets.d.ts.map +1 -0
- package/dist/codex-hooks-assets.js +287 -0
- package/dist/codex-hooks-assets.js.map +1 -0
- package/dist/codex-hooks-verify.d.ts +74 -0
- package/dist/codex-hooks-verify.d.ts.map +1 -0
- package/dist/codex-hooks-verify.js +140 -0
- package/dist/codex-hooks-verify.js.map +1 -0
- package/dist/codex-hooks.d.ts +258 -0
- package/dist/codex-hooks.d.ts.map +1 -0
- package/dist/codex-hooks.js +391 -0
- package/dist/codex-hooks.js.map +1 -0
- package/dist/discrimination-gate.d.ts +88 -15
- package/dist/discrimination-gate.d.ts.map +1 -1
- package/dist/discrimination-gate.js +343 -51
- package/dist/discrimination-gate.js.map +1 -1
- package/dist/feature-adr-checkpoints.d.ts +22 -0
- package/dist/feature-adr-checkpoints.d.ts.map +1 -1
- package/dist/feature-adr-checkpoints.js +42 -0
- package/dist/feature-adr-checkpoints.js.map +1 -1
- package/dist/feature-adr-routing.d.ts +196 -5
- package/dist/feature-adr-routing.d.ts.map +1 -1
- package/dist/feature-adr-routing.js +538 -54
- package/dist/feature-adr-routing.js.map +1 -1
- package/dist/guard.d.ts +13 -0
- package/dist/guard.d.ts.map +1 -1
- package/dist/guard.js +25 -1
- package/dist/guard.js.map +1 -1
- package/dist/index.d.ts +17 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -4
- package/dist/index.js.map +1 -1
- package/dist/loop-blobs.generated.js +2 -2
- package/dist/loop-blobs.generated.js.map +1 -1
- package/dist/managed-hooks.d.ts +76 -0
- package/dist/managed-hooks.d.ts.map +1 -0
- package/dist/managed-hooks.js +89 -0
- package/dist/managed-hooks.js.map +1 -0
- package/dist/mutation-gate.d.ts +14 -0
- package/dist/mutation-gate.d.ts.map +1 -1
- package/dist/mutation-gate.js +25 -2
- package/dist/mutation-gate.js.map +1 -1
- package/dist/operations.d.ts +153 -0
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +560 -24
- package/dist/operations.js.map +1 -1
- package/dist/parity.d.ts +38 -1
- package/dist/parity.d.ts.map +1 -1
- package/dist/parity.js +78 -5
- package/dist/parity.js.map +1 -1
- package/dist/recall-usage.d.ts +53 -0
- package/dist/recall-usage.d.ts.map +1 -1
- package/dist/recall-usage.js +125 -2
- package/dist/recall-usage.js.map +1 -1
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +14 -26
- package/dist/setup.js.map +1 -1
- package/dist/shell-veto-policy.d.ts +53 -0
- package/dist/shell-veto-policy.d.ts.map +1 -0
- package/dist/shell-veto-policy.js +103 -0
- package/dist/shell-veto-policy.js.map +1 -0
- package/dist/skills.d.ts +86 -1
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +116 -1
- package/dist/skills.js.map +1 -1
- package/dist/targets.d.ts +75 -0
- package/dist/targets.d.ts.map +1 -1
- package/dist/targets.js +160 -0
- package/dist/targets.js.map +1 -1
- package/package.json +20 -19
- package/sbom.json +552 -102
- package/src/agents-policy.ts +338 -0
- package/src/codex-hooks-assets.ts +291 -0
- package/src/codex-hooks-verify.ts +184 -0
- package/src/codex-hooks.ts +571 -0
- package/src/discrimination-gate.ts +456 -58
- package/src/feature-adr-checkpoints.ts +38 -0
- package/src/feature-adr-routing.ts +642 -75
- package/src/guard.ts +36 -1
- package/src/index.ts +118 -2
- package/src/loop-blobs.generated.ts +2 -2
- package/src/managed-hooks.ts +129 -0
- package/src/mutation-gate.ts +24 -2
- package/src/operations.ts +719 -28
- package/src/parity.ts +120 -6
- package/src/recall-usage.ts +184 -1
- package/src/setup.ts +26 -27
- package/src/shell-veto-policy.ts +119 -0
- package/src/skills.ts +174 -1
- package/src/targets.ts +189 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-hooks.js","sourceRoot":"","sources":["../src/codex-hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,36 @@
|
|
|
1
1
|
/** The outcome of running one property test in the base (pre-feature) worktree. */
|
|
2
|
-
export type BaseOutcome = 'pass' | 'fail' | 'error';
|
|
3
|
-
/**
|
|
4
|
-
export type
|
|
2
|
+
export type BaseOutcome = 'pass' | 'fail' | 'error' | 'absent';
|
|
3
|
+
/** The outcome of the TIP control run — the same test against the LIVE tree (feature present). */
|
|
4
|
+
export type TipOutcome = 'pass' | 'fail' | 'error';
|
|
5
|
+
/** Per-property verdict after classification. Seven values (ADR-001) — the pre-epoch four collapsed
|
|
6
|
+
* absence, both-rev breakage, and a tip-red test into `DISCRIMINATES_VIA_ERROR`'s near-pass. */
|
|
7
|
+
export type DiscriminationVerdict = 'DISCRIMINATES' | 'DISCRIMINATES_VIA_ERROR' | 'NON_DISCRIMINATING' | 'CANNOT_ISOLATE' | 'TEST_FILE_ABSENT' | 'LOAD_ERROR_AT_BOTH_REVS' | 'FAILS_AT_TIP';
|
|
8
|
+
/** Runner identity for the evidence model. ADR-001's spelling is normative for the PUBLISHED type;
|
|
9
|
+
* mutation-gate's internal `RunnerKind` says `'unknown'` and is mapped here (H2) rather than renamed —
|
|
10
|
+
* mutation-gate stays untouched beyond the `detectRunnerKind` extraction. */
|
|
11
|
+
export type EvidenceRunner = 'vitest' | 'node-test' | 'unrecognised';
|
|
12
|
+
/** How the run went, as read off the output shape (mutation-gate's `RunFailureClassification.kind`
|
|
13
|
+
* plus `'none'` for a green run — `classifyRunFailure` classifies RED runs only, H3). */
|
|
14
|
+
export type EvidenceFailureKind = 'assertions' | 'file-load' | 'none' | 'unrecognised';
|
|
15
|
+
/** RECOGNIZED PROCESS-OUTPUT EVIDENCE for one run. Present in TYPE optionally (old callers still
|
|
16
|
+
* compile) but required in EFFECT for every trust verdict — that asymmetry IS the ADR-001 fix. */
|
|
17
|
+
export interface ExecutionEvidence {
|
|
18
|
+
/** null = timeout / spawn failure. No evidence bar accepts null ⇒ reason 'timeout'. */
|
|
19
|
+
readonly exitCode: number | null;
|
|
20
|
+
readonly runner: EvidenceRunner;
|
|
21
|
+
readonly failureKind: EvidenceFailureKind;
|
|
22
|
+
/** parsed from the runner's own summary; null = unparseable (never assumed to be ≥ 1). */
|
|
23
|
+
readonly testsExecuted: number | null;
|
|
24
|
+
/** target identity: the named test file appears in the recognized output. */
|
|
25
|
+
readonly targetSeen: boolean;
|
|
26
|
+
/** the classifier's evidence string when it has one (quotable in 08_qe_report.md, K7). */
|
|
27
|
+
readonly evidenceLine?: string;
|
|
28
|
+
}
|
|
29
|
+
/** Why a row degraded to CANNOT_ISOLATE. Typed so the operator repair is machine-derivable — the
|
|
30
|
+
* pre-epoch gate had one untyped bucket that read like "meh, no test", hiding a broken instrument. */
|
|
31
|
+
export type CannotIsolateReason = 'no-execution-evidence' | 'unrecognised-runner-output' | 'no-tests-executed' | 'inconsistent-evidence' | 'tip-control-missing' | 'tip-evidence-missing' | 'timeout';
|
|
32
|
+
export declare const DISCRIMINATION_VERDICTS: readonly DiscriminationVerdict[];
|
|
33
|
+
export declare const CANNOT_ISOLATE_REASONS: readonly CannotIsolateReason[];
|
|
5
34
|
/** A property test mapped from the ADR Confirmation `Required automated check`. */
|
|
6
35
|
export interface PropertyTestRef {
|
|
7
36
|
/** repo-relative path to the NEW test file written for the feature. */
|
|
@@ -9,6 +38,15 @@ export interface PropertyTestRef {
|
|
|
9
38
|
/** optional test-name filter (e.g. vitest `-t`) to run just the property case. */
|
|
10
39
|
readonly name?: string;
|
|
11
40
|
}
|
|
41
|
+
/** One observed row fed back by the executor. */
|
|
42
|
+
export interface ClassifyResultRow {
|
|
43
|
+
readonly file: string;
|
|
44
|
+
readonly name?: string;
|
|
45
|
+
readonly outcome: BaseOutcome;
|
|
46
|
+
readonly evidence?: ExecutionEvidence;
|
|
47
|
+
readonly tipOutcome?: TipOutcome;
|
|
48
|
+
readonly tipEvidence?: ExecutionEvidence;
|
|
49
|
+
}
|
|
12
50
|
export interface DiscriminationPlanInput {
|
|
13
51
|
/** the git ref of pre-feature HEAD — the "base" the property test must fail against. */
|
|
14
52
|
readonly baseRef: string;
|
|
@@ -42,29 +80,43 @@ export interface DiscriminationPlan {
|
|
|
42
80
|
export interface ClassifyInput {
|
|
43
81
|
readonly propertyTests: readonly PropertyTestRef[];
|
|
44
82
|
/** observed base outcome per target file (+optional name), same identity the plan used. */
|
|
45
|
-
readonly results: readonly
|
|
46
|
-
readonly file: string;
|
|
47
|
-
readonly name?: string;
|
|
48
|
-
readonly outcome: BaseOutcome;
|
|
49
|
-
}[];
|
|
83
|
+
readonly results: readonly ClassifyResultRow[];
|
|
50
84
|
}
|
|
51
85
|
export interface PerTestVerdict {
|
|
52
86
|
readonly file: string;
|
|
53
87
|
readonly name?: string;
|
|
54
88
|
readonly verdict: DiscriminationVerdict;
|
|
89
|
+
/** present iff verdict === 'CANNOT_ISOLATE'. */
|
|
90
|
+
readonly reason?: CannotIsolateReason;
|
|
55
91
|
}
|
|
56
92
|
export interface DiscriminationFinding {
|
|
57
|
-
/** high
|
|
93
|
+
/** high for every unestablished/false-green state; info only for the VIA_ERROR inference.
|
|
94
|
+
* Never a hard blocker (dz's rule — a false gate kills trust; the owner decides). */
|
|
58
95
|
readonly severity: 'high' | 'info';
|
|
96
|
+
/** which non-clean verdict this finding reports. */
|
|
97
|
+
readonly verdict: DiscriminationVerdict;
|
|
98
|
+
/** the targets carrying that verdict. */
|
|
99
|
+
readonly files: readonly string[];
|
|
59
100
|
readonly title: string;
|
|
101
|
+
/** names THIS verdict's operator action, so nothing rides on the primaryAction tie-break. */
|
|
60
102
|
readonly detail: string;
|
|
61
103
|
}
|
|
104
|
+
/** The INSTRUMENT axis, orthogonal to the product axis a single scalar was forced to carry. */
|
|
105
|
+
export type MeasurementValid = boolean | 'partial';
|
|
106
|
+
/** The single most urgent operator repair, derived from the worst-ranked verdict present. */
|
|
107
|
+
export type PrimaryAction = 'none' | 'strengthen-test' | 'create-missing-test' | 'fix-runner-invocation' | 'fix-red-feature-test' | 'map-a-test';
|
|
62
108
|
export interface DiscriminationResult {
|
|
63
109
|
readonly perTest: readonly PerTestVerdict[];
|
|
64
|
-
/**
|
|
110
|
+
/** compat scalar: worst-of via RANK. A total order can only answer "worst thing present" —
|
|
111
|
+
* everything it destroys travels in findings[] / measurementValid / primaryAction. */
|
|
65
112
|
readonly aggregate: DiscriminationVerdict;
|
|
66
|
-
/**
|
|
113
|
+
/** @deprecated compat alias for ONE release — always `findings[0] ?? null` (worst first).
|
|
114
|
+
* Removal in the next minor is a recorded release obligation (ADR-002 Decision item 6). */
|
|
67
115
|
readonly finding: DiscriminationFinding | null;
|
|
116
|
+
/** one per distinct non-clean verdict present, worst-first. */
|
|
117
|
+
readonly findings: readonly DiscriminationFinding[];
|
|
118
|
+
readonly measurementValid: MeasurementValid;
|
|
119
|
+
readonly primaryAction: PrimaryAction;
|
|
68
120
|
}
|
|
69
121
|
/**
|
|
70
122
|
* Plan the discrimination check. Pure: validates inputs, drops unsafe refs (never silently), and emits the
|
|
@@ -72,10 +124,31 @@ export interface DiscriminationResult {
|
|
|
72
124
|
*/
|
|
73
125
|
export declare function planDiscriminationCheck(input: DiscriminationPlanInput): DiscriminationPlan;
|
|
74
126
|
/**
|
|
75
|
-
* Classify
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
127
|
+
* Classify ONE captured run into RECOGNIZED PROCESS-OUTPUT EVIDENCE. This is the function the
|
|
128
|
+
* pre-epoch gate did not have: it answers "did a runner I can read demonstrably execute THIS file?"
|
|
129
|
+
* instead of trusting the caller's outcome word. Three branches, exactly as ADR-001 specifies:
|
|
130
|
+
*
|
|
131
|
+
* exitCode === null the run timed out or never spawned — nothing is known. No bar accepts it,
|
|
132
|
+
* so the row degrades to CANNOT_ISOLATE reason 'timeout' (same posture as
|
|
133
|
+
* mutation-gate.ts:549 — a hung runner is a loud non-answer, never a pass).
|
|
134
|
+
* exitCode === 0 green: runner from the output SHAPE, failureKind 'none', testsExecuted from
|
|
135
|
+
* the green summary.
|
|
136
|
+
* exitCode !== 0 red: delegate to classifyRunFailure — the SAME classifier that replaced
|
|
137
|
+
* mutation-gate's ad-hoc regexes, so load-vs-assert is decided once per repo.
|
|
138
|
+
*
|
|
139
|
+
* `targetSeen` is a plain substring test over the SGR-stripped output: the bar is target IDENTITY
|
|
140
|
+
* ("the output names the file we asked about"), not authorship. No resistance to an output-imitating
|
|
141
|
+
* runner is claimed (ADR-001 Consequences, hole b) — the honest, narrowed contract.
|
|
142
|
+
*/
|
|
143
|
+
export declare function classifyExecutionEvidence(rawOutput: string, exitCode: number | null, targetFile: string): ExecutionEvidence;
|
|
144
|
+
/**
|
|
145
|
+
* Classify observed base outcomes (+ evidence + the tip control) into per-test verdicts, the compat
|
|
146
|
+
* aggregate, the full findings[] list, and the two orthogonal axes.
|
|
147
|
+
*
|
|
148
|
+
* Every constituent is evidence-gated FIRST; verdict combination is consulted only over EVIDENCED
|
|
149
|
+
* constituents. Old callers that pass bare outcome values (no evidence, no tipOutcome) therefore
|
|
150
|
+
* degrade to a loud CANNOT_ISOLATE — never to a near-pass and never to a false DISCRIMINATES. That
|
|
151
|
+
* runtime behavior change for compiling callers is the ADR-002 headline, not a side effect.
|
|
79
152
|
*/
|
|
80
153
|
export declare function classifyDiscrimination(input: ClassifyInput): DiscriminationResult;
|
|
81
154
|
//# sourceMappingURL=discrimination-gate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discrimination-gate.d.ts","sourceRoot":"","sources":["../src/discrimination-gate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"discrimination-gate.d.ts","sourceRoot":"","sources":["../src/discrimination-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
// EPOCH: before the wave1-instrument-repair release, DISCRIMINATES_VIA_ERROR could mask absent files,
|
|
2
|
+
// both-rev load errors, and tip-red tests, and DISCRIMINATES could be minted without execution evidence;
|
|
3
|
+
// the 47 pre-epoch reports under features/ are historical and are not relabeled.
|
|
4
|
+
//
|
|
5
|
+
// Read that sentence as a dating stamp on every §42 verdict this repo has ever recorded. The pre-epoch
|
|
6
|
+
// gate classified an OUTCOME VALUE ('fail' ⇒ DISCRIMINATES) with no proof that a runner ever executed
|
|
7
|
+
// the named test: MEASURED pre-fix, `dz discrimination-check --test <a real test> --runner false --base
|
|
8
|
+
// HEAD --json` returned `"aggregate": "DISCRIMINATES"` (features/wave1-instrument-repair/07_code_changes/
|
|
9
|
+
// acid-red-runs.md, acid A6), and a file that never existed returned `DISCRIMINATES_VIA_ERROR` (acid A1).
|
|
10
|
+
// This module now gates every trust verdict on RECOGNIZED PROCESS-OUTPUT EVIDENCE (ADR-001): the runner's
|
|
11
|
+
// output must match a measured shape AND name the target. Scope honesty: that bar is "a recognized runner
|
|
12
|
+
// demonstrably executed the named test", NOT resistance to an output-imitating runner.
|
|
13
|
+
//
|
|
1
14
|
// §42 test-discrimination gate for feature-adr Step-8.
|
|
2
15
|
//
|
|
3
16
|
// Grounded in cve-bench/scripts/evaluate.mjs (RuvNet), whose §42 loop proves a regression test actually
|
|
@@ -11,6 +24,41 @@
|
|
|
11
24
|
// sandboxed workflow), which feeds the observed per-target outcome back into `classifyDiscrimination`. Same
|
|
12
25
|
// pure-engine + injected-data shape as challenge-panel.ts and routing-outcomes.ts, so it is deterministic and
|
|
13
26
|
// unit-testable without a git repo or a test runner.
|
|
27
|
+
import { classifyRunFailure, countFailingTests, detectRunnerKind } from './mutation-gate.js';
|
|
28
|
+
/**
|
|
29
|
+
* The CLOSED verdict vocabulary, as DATA (QE F6).
|
|
30
|
+
*
|
|
31
|
+
* Derived from an exhaustive `Record<DiscriminationVerdict, true>`, so the exactness is enforced by
|
|
32
|
+
* `tsc` at BUILD time in both directions: adding a union member fails with "Property '<new>' is
|
|
33
|
+
* missing", removing one fails with "does not exist in type". A runtime sweep can only show which
|
|
34
|
+
* values are REACHABLE — it can never see an eighth value that nothing happens to construct, which
|
|
35
|
+
* is exactly the hole the ADR-002 Confirmation-1 gate had. This list closes it and is exported so
|
|
36
|
+
* the release gate can compare "declared" against "reachable" instead of a hand-written literal.
|
|
37
|
+
*
|
|
38
|
+
* (The test directory is excluded from this package's tsconfig, so a `satisfies` written in a test
|
|
39
|
+
* file would never be compiled. The guard has to live here to be real.)
|
|
40
|
+
*/
|
|
41
|
+
const DISCRIMINATION_VERDICT_SET = {
|
|
42
|
+
DISCRIMINATES: true,
|
|
43
|
+
DISCRIMINATES_VIA_ERROR: true,
|
|
44
|
+
NON_DISCRIMINATING: true,
|
|
45
|
+
CANNOT_ISOLATE: true,
|
|
46
|
+
TEST_FILE_ABSENT: true,
|
|
47
|
+
LOAD_ERROR_AT_BOTH_REVS: true,
|
|
48
|
+
FAILS_AT_TIP: true,
|
|
49
|
+
};
|
|
50
|
+
export const DISCRIMINATION_VERDICTS = Object.keys(DISCRIMINATION_VERDICT_SET);
|
|
51
|
+
/** The closed degradation vocabulary, same exhaustive-record discipline. */
|
|
52
|
+
const CANNOT_ISOLATE_REASON_SET = {
|
|
53
|
+
'no-execution-evidence': true,
|
|
54
|
+
'unrecognised-runner-output': true,
|
|
55
|
+
'no-tests-executed': true,
|
|
56
|
+
'inconsistent-evidence': true,
|
|
57
|
+
'tip-control-missing': true,
|
|
58
|
+
'tip-evidence-missing': true,
|
|
59
|
+
timeout: true,
|
|
60
|
+
};
|
|
61
|
+
export const CANNOT_ISOLATE_REASONS = Object.keys(CANNOT_ISOLATE_REASON_SET);
|
|
14
62
|
/** git-ref-safe characters only; rejects shell metacharacters and traversal that would break out of a token. */
|
|
15
63
|
const SAFE_REF = /^[A-Za-z0-9_][A-Za-z0-9_./~^@{}-]{0,199}$/;
|
|
16
64
|
/**
|
|
@@ -82,83 +130,327 @@ export function planDiscriminationCheck(input) {
|
|
|
82
130
|
commands.push(`git worktree remove --force {{WORKTREE}}`);
|
|
83
131
|
return { runnable: true, baseRef, targets, rejected, commands };
|
|
84
132
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
133
|
+
// ── Evidence production (ADR-001's root-disease fix) ─────────────────────────────────────────
|
|
134
|
+
/** ANSI SGR sequences. vitest colours its summary even when piped (MEASURED), which would hide the
|
|
135
|
+
* target path and the green summary from every check below. Terminal encoding, not a runner shape —
|
|
136
|
+
* the runner-shape regex family stays single-sourced in mutation-gate.ts (ADR-001 driver). */
|
|
137
|
+
// eslint-disable-next-line no-control-regex
|
|
138
|
+
const SGR = /\x1b\[[0-9;]*m/g;
|
|
139
|
+
/**
|
|
140
|
+
* Tests EXECUTED in a GREEN run, from the runner's own summary. The green counterpart of
|
|
141
|
+
* mutation-gate's `countFailingTests`: `classifyRunFailure` classifies RED runs only (its green
|
|
142
|
+
* branch returns a red-worded `'unrecognised'`, mutation-gate.ts:404-411), so the ADR's pass bar
|
|
143
|
+
* — "≥ 1 test actually executed" — cannot be answered by delegating a green run to it (H3).
|
|
144
|
+
* Returns null when nothing parses; null NEVER counts as ≥ 1 (a `--passWithNoTests` / `--runner true`
|
|
145
|
+
* green is not an established false green — misdiagnosing it sends the operator to strengthen a test
|
|
146
|
+
* when the RUNNER is broken).
|
|
147
|
+
*/
|
|
148
|
+
function countExecutedTests(rawOutput) {
|
|
149
|
+
const output = rawOutput.replace(SGR, '');
|
|
150
|
+
// node --test / TAP: `# pass N` is authoritative; `# tests N` is the total when pass is absent.
|
|
151
|
+
const tapPass = /^#\s*pass\s+(\d+)\s*$/m.exec(output);
|
|
152
|
+
if (tapPass && tapPass[1] !== undefined)
|
|
153
|
+
return Number(tapPass[1]);
|
|
154
|
+
const tapTests = /^#\s*tests\s+(\d+)\s*$/m.exec(output);
|
|
155
|
+
if (tapTests && tapTests[1] !== undefined)
|
|
156
|
+
return Number(tapTests[1]);
|
|
157
|
+
// vitest: the `Tests` line, NOT `Test Files` (a file count under-reports the executed tests).
|
|
158
|
+
const vitest = /^\s*Tests\s+[^|\n]*?(\d+)\s+passed/m.exec(output);
|
|
159
|
+
if (vitest && vitest[1] !== undefined)
|
|
160
|
+
return Number(vitest[1]);
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
/** mutation-gate's internal `'unknown'` is the PUBLISHED `'unrecognised'` here (H2). */
|
|
164
|
+
function toEvidenceRunner(kind) {
|
|
165
|
+
return kind === 'unknown' ? 'unrecognised' : kind;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Classify ONE captured run into RECOGNIZED PROCESS-OUTPUT EVIDENCE. This is the function the
|
|
169
|
+
* pre-epoch gate did not have: it answers "did a runner I can read demonstrably execute THIS file?"
|
|
170
|
+
* instead of trusting the caller's outcome word. Three branches, exactly as ADR-001 specifies:
|
|
171
|
+
*
|
|
172
|
+
* exitCode === null the run timed out or never spawned — nothing is known. No bar accepts it,
|
|
173
|
+
* so the row degrades to CANNOT_ISOLATE reason 'timeout' (same posture as
|
|
174
|
+
* mutation-gate.ts:549 — a hung runner is a loud non-answer, never a pass).
|
|
175
|
+
* exitCode === 0 green: runner from the output SHAPE, failureKind 'none', testsExecuted from
|
|
176
|
+
* the green summary.
|
|
177
|
+
* exitCode !== 0 red: delegate to classifyRunFailure — the SAME classifier that replaced
|
|
178
|
+
* mutation-gate's ad-hoc regexes, so load-vs-assert is decided once per repo.
|
|
179
|
+
*
|
|
180
|
+
* `targetSeen` is a plain substring test over the SGR-stripped output: the bar is target IDENTITY
|
|
181
|
+
* ("the output names the file we asked about"), not authorship. No resistance to an output-imitating
|
|
182
|
+
* runner is claimed (ADR-001 Consequences, hole b) — the honest, narrowed contract.
|
|
183
|
+
*/
|
|
184
|
+
export function classifyExecutionEvidence(rawOutput, exitCode, targetFile) {
|
|
185
|
+
if (exitCode === null) {
|
|
186
|
+
return { exitCode: null, runner: 'unrecognised', failureKind: 'unrecognised', testsExecuted: null, targetSeen: false };
|
|
187
|
+
}
|
|
188
|
+
const raw = typeof rawOutput === 'string' ? rawOutput : '';
|
|
189
|
+
const targetSeen = typeof targetFile === 'string' && targetFile.length > 0 && raw.replace(SGR, '').includes(targetFile);
|
|
190
|
+
if (exitCode === 0) {
|
|
191
|
+
return {
|
|
192
|
+
exitCode,
|
|
193
|
+
runner: toEvidenceRunner(detectRunnerKind(raw)),
|
|
194
|
+
failureKind: 'none',
|
|
195
|
+
testsExecuted: countExecutedTests(raw),
|
|
196
|
+
targetSeen,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const red = classifyRunFailure(raw);
|
|
200
|
+
const base = {
|
|
201
|
+
exitCode,
|
|
202
|
+
runner: toEvidenceRunner(red.runner),
|
|
203
|
+
failureKind: red.kind,
|
|
204
|
+
testsExecuted: countFailingTests(raw),
|
|
205
|
+
targetSeen,
|
|
206
|
+
};
|
|
207
|
+
// exactOptionalPropertyTypes: an absent evidence line is OMITTED, never set to undefined.
|
|
208
|
+
return red.evidence !== undefined ? { ...base, evidenceLine: red.evidence } : base;
|
|
209
|
+
}
|
|
210
|
+
const EVIDENCED = { evidenced: true };
|
|
211
|
+
function degraded(reason) {
|
|
212
|
+
return { evidenced: false, reason };
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Is this observation EVIDENCED? Applied to the base observation and (independently) to the tip
|
|
216
|
+
* control, BEFORE any verdict combination — uniform precedence, uniquely implementable: no verdict,
|
|
217
|
+
* trust OR alarm, fires from an unevidenced runner constituent.
|
|
218
|
+
*
|
|
219
|
+
* PARSE-NEVER-SYNTHESIZE: an outcome value CONTRADICTED by its own evidence (`fail` + `file-load`,
|
|
220
|
+
* `error` + `assertions`, `pass` + a non-zero exit, and — symmetrically — any RED outcome with
|
|
221
|
+
* exit 0) is REJECTED as 'inconsistent-evidence' and never
|
|
222
|
+
* reinterpreted to the evidence-implied outcome. Guessing which half to trust would re-open exactly
|
|
223
|
+
* the value-trusting hole this rewrite closes — a caller whose value and observation disagree is a
|
|
224
|
+
* broken executor, and a broken executor is a non-answer.
|
|
225
|
+
*/
|
|
226
|
+
function gateObservation(outcome, evidence) {
|
|
227
|
+
if (!evidence || typeof evidence !== 'object')
|
|
228
|
+
return degraded('no-execution-evidence');
|
|
229
|
+
if (evidence.exitCode === null)
|
|
230
|
+
return degraded('timeout');
|
|
231
|
+
if (evidence.runner === 'unrecognised')
|
|
232
|
+
return degraded('unrecognised-runner-output');
|
|
233
|
+
if (outcome === 'pass') {
|
|
234
|
+
if (evidence.exitCode !== 0)
|
|
235
|
+
return degraded('inconsistent-evidence');
|
|
236
|
+
if (evidence.failureKind !== 'none')
|
|
237
|
+
return degraded('inconsistent-evidence');
|
|
238
|
+
// null testsExecuted is NOT ≥ 1: an unparseable summary proves no test ran (driver 3).
|
|
239
|
+
if (evidence.testsExecuted === null || evidence.testsExecuted < 1)
|
|
240
|
+
return degraded('no-tests-executed');
|
|
241
|
+
if (!evidence.targetSeen)
|
|
242
|
+
return degraded('no-execution-evidence');
|
|
243
|
+
return EVIDENCED;
|
|
244
|
+
}
|
|
245
|
+
if (outcome === 'fail') {
|
|
246
|
+
// QE F1: a RED outcome with exit 0 is an inconsistent tuple, symmetrically with `pass` + a
|
|
247
|
+
// non-zero exit. The exit code is the runner's own primary verdict; a caller reporting "it
|
|
248
|
+
// failed" over a process that exited SUCCESSFULLY is a broken executor, and accepting it let a
|
|
249
|
+
// fabricated evidence object mint DISCRIMINATES (MEASURED: `{outcome:'fail', evidence:
|
|
250
|
+
// {exitCode:0, runner:'vitest', failureKind:'assertions', testsExecuted:1, targetSeen:true}}`
|
|
251
|
+
// returned aggregate DISCRIMINATES, measurementValid true).
|
|
252
|
+
if (evidence.exitCode === 0)
|
|
253
|
+
return degraded('inconsistent-evidence');
|
|
254
|
+
if (evidence.failureKind === 'file-load' || evidence.failureKind === 'none')
|
|
255
|
+
return degraded('inconsistent-evidence');
|
|
256
|
+
// a RECOGNIZED runner whose red output carries no classifiable failure: the redness has no
|
|
257
|
+
// readable source, so it is the same non-answer as an unreadable runner.
|
|
258
|
+
if (evidence.failureKind === 'unrecognised')
|
|
259
|
+
return degraded('unrecognised-runner-output');
|
|
260
|
+
if (!evidence.targetSeen)
|
|
261
|
+
return degraded('no-execution-evidence');
|
|
262
|
+
return EVIDENCED;
|
|
263
|
+
}
|
|
264
|
+
// outcome === 'error' — the bar is recognized FILE-LOAD redness. targetSeen is not required: a
|
|
265
|
+
// module that dies at import can legitimately be reported by the importing suite's name.
|
|
266
|
+
// QE F1: same exit-code symmetry as the fail branch — a run that exited 0 did not error.
|
|
267
|
+
if (evidence.exitCode === 0)
|
|
268
|
+
return degraded('inconsistent-evidence');
|
|
269
|
+
if (evidence.failureKind === 'assertions' || evidence.failureKind === 'none')
|
|
270
|
+
return degraded('inconsistent-evidence');
|
|
271
|
+
if (evidence.failureKind === 'unrecognised')
|
|
272
|
+
return degraded('unrecognised-runner-output');
|
|
273
|
+
return EVIDENCED;
|
|
274
|
+
}
|
|
275
|
+
function cannotIsolate(reason) {
|
|
276
|
+
return { verdict: 'CANNOT_ISOLATE', reason };
|
|
93
277
|
}
|
|
94
|
-
/**
|
|
278
|
+
/**
|
|
279
|
+
* One row → one verdict. Reading order IS the matrix's precedence: absence (layer-1 stat, the one
|
|
280
|
+
* principled evidence exemption — no runner ran, so none is applicable), then the base gate, then
|
|
281
|
+
* — only for an EVIDENCED base error — the tip control.
|
|
282
|
+
*
|
|
283
|
+
* The tip is consulted ONLY under an evidenced base error. Without a classified tip redness,
|
|
284
|
+
* LOAD_ERROR_AT_BOTH_REVS and FAILS_AT_TIP cannot be told apart, so claiming either would synthesize.
|
|
285
|
+
*/
|
|
286
|
+
function classifyRow(row) {
|
|
287
|
+
if (row === undefined)
|
|
288
|
+
return cannotIsolate('no-execution-evidence');
|
|
289
|
+
if (row.outcome === 'absent')
|
|
290
|
+
return { verdict: 'TEST_FILE_ABSENT' };
|
|
291
|
+
const baseGate = gateObservation(row.outcome, row.evidence);
|
|
292
|
+
if (!baseGate.evidenced)
|
|
293
|
+
return cannotIsolate(baseGate.reason);
|
|
294
|
+
if (row.outcome === 'fail')
|
|
295
|
+
return { verdict: 'DISCRIMINATES' };
|
|
296
|
+
if (row.outcome === 'pass')
|
|
297
|
+
return { verdict: 'NON_DISCRIMINATING' };
|
|
298
|
+
// EVIDENCED base error — the only cell where the tip control decides.
|
|
299
|
+
if (row.tipOutcome === undefined)
|
|
300
|
+
return cannotIsolate('tip-control-missing');
|
|
301
|
+
const tipGate = gateObservation(row.tipOutcome, row.tipEvidence);
|
|
302
|
+
if (!tipGate.evidenced) {
|
|
303
|
+
// a tip that TIMED OUT is named as such; every other unevidenced tip is 'tip-evidence-missing'.
|
|
304
|
+
return cannotIsolate(tipGate.reason === 'timeout' ? 'timeout' : 'tip-evidence-missing');
|
|
305
|
+
}
|
|
306
|
+
if (row.tipOutcome === 'pass')
|
|
307
|
+
return { verdict: 'DISCRIMINATES_VIA_ERROR' };
|
|
308
|
+
if (row.tipOutcome === 'error')
|
|
309
|
+
return { verdict: 'LOAD_ERROR_AT_BOTH_REVS' };
|
|
310
|
+
return { verdict: 'FAILS_AT_TIP' };
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Severity rank for the compat aggregate. The unestablished band's ordering (5 > 4 > 3 > 2) is
|
|
314
|
+
* unchanged from the original decision: absence of the instrument's subject (a broken promise —
|
|
315
|
+
* the historically exploited channel) outranks an active misconfiguration, which outranks positive
|
|
316
|
+
* evidence of a currently-red named check, which outranks mere absence of an observation.
|
|
317
|
+
*/
|
|
95
318
|
const RANK = {
|
|
96
|
-
NON_DISCRIMINATING:
|
|
319
|
+
NON_DISCRIMINATING: 6,
|
|
320
|
+
TEST_FILE_ABSENT: 5,
|
|
321
|
+
LOAD_ERROR_AT_BOTH_REVS: 4,
|
|
322
|
+
FAILS_AT_TIP: 3,
|
|
97
323
|
CANNOT_ISOLATE: 2,
|
|
98
324
|
DISCRIMINATES_VIA_ERROR: 1,
|
|
99
325
|
DISCRIMINATES: 0,
|
|
100
326
|
};
|
|
327
|
+
/** Verdicts that mean the instrument MEASURED (even when the news is bad). */
|
|
328
|
+
const ESTABLISHED = ['DISCRIMINATES', 'DISCRIMINATES_VIA_ERROR', 'NON_DISCRIMINATING'];
|
|
329
|
+
const SEVERITY_OF = {
|
|
330
|
+
NON_DISCRIMINATING: 'high',
|
|
331
|
+
TEST_FILE_ABSENT: 'high',
|
|
332
|
+
LOAD_ERROR_AT_BOTH_REVS: 'high',
|
|
333
|
+
FAILS_AT_TIP: 'high',
|
|
334
|
+
CANNOT_ISOLATE: 'high', // was info pre-epoch: a degraded reading that reads advisory gets ignored.
|
|
335
|
+
DISCRIMINATES_VIA_ERROR: 'info',
|
|
336
|
+
DISCRIMINATES: 'info',
|
|
337
|
+
};
|
|
338
|
+
const TITLE_OF = {
|
|
339
|
+
NON_DISCRIMINATING: 'non-discriminating property test (false green)',
|
|
340
|
+
TEST_FILE_ABSENT: 'named property test is not a regular file',
|
|
341
|
+
LOAD_ERROR_AT_BOTH_REVS: 'property test could not execute at EITHER rev (zero signal)',
|
|
342
|
+
FAILS_AT_TIP: "the feature's own property test is RED with the feature present",
|
|
343
|
+
CANNOT_ISOLATE: 'discrimination could not be established (degraded reading)',
|
|
344
|
+
DISCRIMINATES_VIA_ERROR: 'discrimination inferred via load error',
|
|
345
|
+
DISCRIMINATES: '',
|
|
346
|
+
};
|
|
347
|
+
const ACTION_OF = {
|
|
348
|
+
NON_DISCRIMINATING: 'strengthen-test',
|
|
349
|
+
TEST_FILE_ABSENT: 'create-missing-test',
|
|
350
|
+
LOAD_ERROR_AT_BOTH_REVS: 'fix-runner-invocation',
|
|
351
|
+
FAILS_AT_TIP: 'fix-red-feature-test',
|
|
352
|
+
CANNOT_ISOLATE: 'fix-runner-invocation',
|
|
353
|
+
DISCRIMINATES_VIA_ERROR: 'none',
|
|
354
|
+
DISCRIMINATES: 'none',
|
|
355
|
+
};
|
|
356
|
+
function describe(p) {
|
|
357
|
+
const named = p.name ? `${p.file} (${p.name})` : p.file;
|
|
358
|
+
return p.reason ? `${named} [reason: ${p.reason}]` : named;
|
|
359
|
+
}
|
|
360
|
+
function detailFor(verdict, rows, extra) {
|
|
361
|
+
const list = rows.map(describe).join(', ');
|
|
362
|
+
const tail = extra.length > 0 ? ` ${extra.join(' ')}` : '';
|
|
363
|
+
switch (verdict) {
|
|
364
|
+
case 'NON_DISCRIMINATING':
|
|
365
|
+
return `${rows.length} property test(s) PASS at pre-feature base WITH execution evidence — they do not exercise the ADR safety property and would stay green if the fix regressed: ${list}. Action: strengthen-test (make the assertion fail without the feature diff). (Advisory — the pipeline continues; the owner decides.)`;
|
|
366
|
+
case 'TEST_FILE_ABSENT':
|
|
367
|
+
return `the named check is not a regular file in the working tree (stat + isFile, before any worktree): ${list}.${tail} Action: create-missing-test — an ADR Confirmation naming a file that does not exist is a broken promise, never a pass.`;
|
|
368
|
+
case 'LOAD_ERROR_AT_BOTH_REVS':
|
|
369
|
+
return `the test errored at the pre-feature base AND at tip: ${list}. The instrument could not execute it at either rev, so the reading carries ZERO signal about discrimination. Action: fix-runner-invocation (wrong runner for this file type, or a broken config).`;
|
|
370
|
+
case 'FAILS_AT_TIP':
|
|
371
|
+
return `the test errored at base and fails BY ASSERTION at tip: ${list}. The feature's own property test is red with the feature present, so discrimination is unestablishable. Action: fix-red-feature-test — grade the feature code accordingly.`;
|
|
372
|
+
case 'CANNOT_ISOLATE':
|
|
373
|
+
return `no ESTABLISHED observation for: ${list}. A degraded reading is not a pass and not a failure — it means the instrument did not measure. Action: map-a-test when no test was mapped/ran, otherwise fix-runner-invocation.`;
|
|
374
|
+
case 'DISCRIMINATES_VIA_ERROR':
|
|
375
|
+
return `the property test could not LOAD at pre-feature base and PASSES at tip, both with execution evidence: ${list}. Discrimination is INFERRED from that pair, not proven by an assertion — acceptable, but a green-path assertion would be stronger.`;
|
|
376
|
+
default:
|
|
377
|
+
return '';
|
|
378
|
+
}
|
|
379
|
+
}
|
|
101
380
|
/**
|
|
102
|
-
* Classify observed base outcomes
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
381
|
+
* Classify observed base outcomes (+ evidence + the tip control) into per-test verdicts, the compat
|
|
382
|
+
* aggregate, the full findings[] list, and the two orthogonal axes.
|
|
383
|
+
*
|
|
384
|
+
* Every constituent is evidence-gated FIRST; verdict combination is consulted only over EVIDENCED
|
|
385
|
+
* constituents. Old callers that pass bare outcome values (no evidence, no tipOutcome) therefore
|
|
386
|
+
* degrade to a loud CANNOT_ISOLATE — never to a near-pass and never to a false DISCRIMINATES. That
|
|
387
|
+
* runtime behavior change for compiling callers is the ADR-002 headline, not a side effect.
|
|
106
388
|
*/
|
|
107
389
|
export function classifyDiscrimination(input) {
|
|
108
390
|
const results = Array.isArray(input.results) ? input.results : [];
|
|
109
391
|
const byKey = new Map();
|
|
110
392
|
for (const r of results) {
|
|
111
393
|
if (r && typeof r.file === 'string')
|
|
112
|
-
byKey.set(`${r.file}|${r.name ?? ''}`, r
|
|
394
|
+
byKey.set(`${r.file}|${r.name ?? ''}`, r);
|
|
113
395
|
}
|
|
114
396
|
const propertyTests = Array.isArray(input.propertyTests) ? input.propertyTests : [];
|
|
115
397
|
if (propertyTests.length === 0) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
398
|
+
// No mapped test at all: the instrument has no subject. HIGH, because a degraded reading that
|
|
399
|
+
// renders as advisory is the one an operator skips.
|
|
400
|
+
const finding = {
|
|
401
|
+
severity: 'high',
|
|
402
|
+
verdict: 'CANNOT_ISOLATE',
|
|
403
|
+
files: [],
|
|
404
|
+
title: 'discrimination gate: no property test to check',
|
|
405
|
+
detail: 'No test was mapped to the ADR safety property, so discrimination could not be evaluated — this is the existing "property untested" finding. Action: map-a-test.',
|
|
124
406
|
};
|
|
407
|
+
return { perTest: [], aggregate: 'CANNOT_ISOLATE', finding, findings: [finding], measurementValid: false, primaryAction: 'map-a-test' };
|
|
125
408
|
}
|
|
409
|
+
let missingRow = false;
|
|
126
410
|
const perTest = propertyTests.map((t) => {
|
|
127
411
|
const file = typeof t.file === 'string' ? t.file : '';
|
|
128
412
|
const name = typeof t.name === 'string' ? t.name : undefined;
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
413
|
+
const row = byKey.get(`${file}|${name ?? ''}`);
|
|
414
|
+
if (row === undefined)
|
|
415
|
+
missingRow = true;
|
|
416
|
+
const rv = classifyRow(row);
|
|
417
|
+
// exactOptionalPropertyTypes: `name`/`reason` are OMITTED when absent, never set to undefined.
|
|
418
|
+
const base = name !== undefined ? { file, name, verdict: rv.verdict } : { file, verdict: rv.verdict };
|
|
419
|
+
return rv.reason !== undefined ? { ...base, reason: rv.reason } : base;
|
|
132
420
|
});
|
|
133
421
|
let aggregate = 'DISCRIMINATES';
|
|
134
422
|
for (const p of perTest)
|
|
135
423
|
if (RANK[p.verdict] > RANK[aggregate])
|
|
136
424
|
aggregate = p.verdict;
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
detail: 'The property test could not load at pre-feature base (it references feature code that does not exist yet), so discrimination is INFERRED, not proven by an assertion. Acceptable, but a green-path assertion would be stronger.',
|
|
425
|
+
// findings[]: ONE per distinct non-clean verdict present, worst-first. The scalar aggregate can
|
|
426
|
+
// only name the worst state; a corpus with a false green AND an absent file must report BOTH.
|
|
427
|
+
const distinct = [...new Set(perTest.map((p) => p.verdict))]
|
|
428
|
+
.filter((v) => v !== 'DISCRIMINATES')
|
|
429
|
+
.sort((a, b) => RANK[b] - RANK[a]);
|
|
430
|
+
const findings = distinct.map((verdict) => {
|
|
431
|
+
const rows = perTest.filter((p) => p.verdict === verdict);
|
|
432
|
+
// the CLI reports a directory-at-the-path out of band (absent rows never consult the evidence
|
|
433
|
+
// gate, matrix row 1), so its `not-a-regular-file` note rides into the finding detail here.
|
|
434
|
+
const extra = verdict === 'TEST_FILE_ABSENT'
|
|
435
|
+
? [
|
|
436
|
+
...new Set(rows
|
|
437
|
+
.map((p) => byKey.get(`${p.file}|${p.name ?? ''}`)?.evidence?.evidenceLine)
|
|
438
|
+
.filter((l) => typeof l === 'string' && l.length > 0)),
|
|
439
|
+
]
|
|
440
|
+
: [];
|
|
441
|
+
return {
|
|
442
|
+
severity: SEVERITY_OF[verdict],
|
|
443
|
+
verdict,
|
|
444
|
+
files: rows.map((p) => p.file),
|
|
445
|
+
title: TITLE_OF[verdict],
|
|
446
|
+
detail: detailFor(verdict, rows, extra),
|
|
160
447
|
};
|
|
161
|
-
}
|
|
162
|
-
|
|
448
|
+
});
|
|
449
|
+
const established = perTest.filter((p) => ESTABLISHED.includes(p.verdict)).length;
|
|
450
|
+
const measurementValid = established === perTest.length ? true : established === 0 ? false : 'partial';
|
|
451
|
+
// primaryAction: the worst-ranked verdict's action. CANNOT_ISOLATE splits — a target with no
|
|
452
|
+
// mapped/observed row is a MAPPING repair; every other degradation is an INVOCATION repair.
|
|
453
|
+
const primaryAction = aggregate === 'CANNOT_ISOLATE' && missingRow ? 'map-a-test' : ACTION_OF[aggregate];
|
|
454
|
+
return { perTest, aggregate, finding: findings[0] ?? null, findings, measurementValid, primaryAction };
|
|
163
455
|
}
|
|
164
456
|
//# sourceMappingURL=discrimination-gate.js.map
|