eval-quality 0.2.0 → 0.3.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/README.md +3 -3
- package/corpus/dev/README.md +3 -2
- package/corpus/dev/compile-seal-example/brief.json +1 -1
- package/corpus/dev/compile-seal-example/contract.json +1 -1
- package/corpus/dev/contracts/absent-collection-locations.json +1 -1
- package/corpus/dev/contracts/absent-sibling-groups.json +1 -1
- package/corpus/dev/contracts/absent-success-indicator.json +1 -1
- package/corpus/dev/contracts/empty-channel-roles.json +1 -1
- package/corpus/dev/contracts/empty-collection-locations.json +1 -1
- package/corpus/dev/contracts/empty-request-shapes.json +1 -1
- package/corpus/dev/contracts/empty-sibling-groups.json +1 -1
- package/corpus/dev/contracts/fragment-selection.json +1 -0
- package/corpus/dev/contracts/no-collection-quantifier.json +1 -1
- package/corpus/dev/contracts/no-operation-inventory.json +1 -1
- package/corpus/dev/contracts/no-read-back-relation.json +1 -1
- package/corpus/dev/contracts/no-state-change-marker.json +1 -1
- package/corpus/dev/contracts/no-type-violating-step.json +1 -1
- package/corpus/dev/contracts/per-key-split-oracles.json +1 -1
- package/corpus/dev/contracts/review-corpus.json +1 -0
- package/corpus/dev/contracts/satisfied-declarations.json +1 -1
- package/corpus/dev/contracts/single-required-response-key.json +1 -1
- package/corpus/dev/contracts/split-indicator-oracle.json +1 -1
- package/corpus/dev/contracts/unaddressed-parameter-sibling.json +1 -1
- package/corpus/dev/contracts/unnamed-reference-set.json +1 -1
- package/corpus/dev/contracts/wrong-cardinality-form.json +1 -1
- package/corpus/dev/index.json +1 -1
- package/dist/cli/render.d.ts +2 -5
- package/dist/cli/render.js +51 -1
- package/dist/core/compile/bindings.d.ts +26 -7
- package/dist/core/compile/bindings.js +49 -32
- package/dist/core/compile/compile.d.ts +12 -0
- package/dist/core/compile/compile.js +28 -1
- package/dist/core/compile/excluded-content.d.ts +11 -0
- package/dist/core/compile/excluded-content.js +42 -0
- package/dist/core/compile/expression-legality.d.ts +2 -2
- package/dist/core/compile/expression-legality.js +58 -12
- package/dist/core/compile/interface-inventory.d.ts +34 -1
- package/dist/core/compile/interface-inventory.js +88 -11
- package/dist/core/compile/reachability.d.ts +12 -2
- package/dist/core/compile/reachability.js +123 -36
- package/dist/core/compile/schema-version.d.ts +2 -0
- package/dist/core/compile/schema-version.js +25 -0
- package/dist/core/compile/sensitivity-witness.d.ts +31 -12
- package/dist/core/compile/sensitivity-witness.js +110 -23
- package/dist/core/compile/step-reference.d.ts +2 -0
- package/dist/core/compile/step-reference.js +49 -0
- package/dist/core/coverage/operations.d.ts +62 -0
- package/dist/core/coverage/operations.js +57 -0
- package/dist/core/coverage/relevance.d.ts +4 -2
- package/dist/core/coverage/relevance.js +22 -23
- package/dist/core/coverage/satisfaction.d.ts +2 -2
- package/dist/core/coverage/satisfaction.js +73 -48
- package/dist/core/declared-inputs.d.ts +83 -4
- package/dist/core/declared-inputs.js +105 -8
- package/dist/core/evaluate/evidence-resolution.d.ts +9 -12
- package/dist/core/evaluate/evidence-resolution.js +70 -10
- package/dist/core/evaluate/operators.d.ts +22 -0
- package/dist/core/evaluate/operators.js +17 -1
- package/dist/core/evaluate/resolution.d.ts +14 -3
- package/dist/core/evaluate/resolution.js +63 -3
- package/dist/core/excluded-content.d.ts +65 -0
- package/dist/core/excluded-content.js +113 -0
- package/dist/core/failure-codes.d.ts +2 -2
- package/dist/core/failure-codes.js +5 -2
- package/dist/core/ingest/conditions.d.ts +1 -1
- package/dist/core/ingest/ingest.js +8 -0
- package/dist/core/preflight/plan.d.ts +7 -5
- package/dist/core/preflight/plan.js +75 -32
- package/dist/core/preflight/projection.d.ts +6 -3
- package/dist/core/preflight/projection.js +22 -2
- package/dist/core/preflight/reduce.js +47 -7
- package/dist/core/preflight/witness-evidence.d.ts +5 -5
- package/dist/core/preflight/witness-evidence.js +63 -20
- package/dist/core/schemas/artifact.d.ts +683 -35
- package/dist/core/schemas/constraint-ledger.js +11 -0
- package/dist/core/schemas/defect-signature.d.ts +438 -16
- package/dist/core/schemas/defect-signature.js +58 -10
- package/dist/core/schemas/eval-contract.d.ts +517 -12
- package/dist/core/schemas/eval-contract.js +18 -2
- package/dist/core/schemas/evidence-artifact.d.ts +14 -4
- package/dist/core/schemas/evidence-artifact.js +1 -1
- package/dist/core/schemas/interface.d.ts +741 -13
- package/dist/core/schemas/interface.js +120 -7
- package/dist/core/schemas/isolation-manifest.js +16 -9
- package/dist/core/schemas/plan.d.ts +217 -3
- package/dist/core/schemas/plan.js +22 -1
- package/dist/core/schemas/pointer.d.ts +47 -1
- package/dist/core/schemas/pointer.js +89 -8
- package/dist/core/schemas/port-messages.d.ts +194 -10
- package/dist/core/schemas/port-messages.js +73 -6
- package/dist/core/schemas/probe-body.d.ts +18 -0
- package/dist/core/schemas/probe-body.js +13 -0
- package/dist/core/schemas/probe.d.ts +122 -3
- package/dist/core/schemas/probe.js +1 -1
- package/dist/core/schemas/sealed-run-record.d.ts +131 -9
- package/dist/core/schemas/sealed-run-record.js +56 -11
- package/dist/core/schemas/sensitivity-witness.d.ts +108 -6
- package/dist/core/schemas/sensitivity-witness.js +61 -5
- package/dist/core/score/bindings.d.ts +2 -2
- package/dist/core/score/bindings.js +25 -13
- package/dist/core/score/qualification.d.ts +5 -5
- package/dist/core/score/qualification.js +67 -37
- package/dist/core/score/quotation.d.ts +1 -24
- package/dist/core/score/quotation.js +29 -4
- package/dist/core/score/score.js +28 -2
- package/dist/core/score/strength.d.ts +9 -0
- package/dist/core/score/strength.js +35 -1
- package/dist/core/score/witness.d.ts +21 -0
- package/dist/core/score/witness.js +9 -4
- package/dist/core/seal/derived-reference.d.ts +2 -9
- package/dist/core/seal/derived-reference.js +62 -23
- package/dist/core/seal/plan-index.d.ts +18 -3
- package/dist/core/seal/plan-index.js +44 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/ports/environment-probe-port.d.ts +60 -4
- package/dist/testing/probe-conformance.d.ts +29 -0
- package/dist/testing/probe-conformance.js +34 -5
- package/package.json +1 -1
- package/schemas/eval-contract.schema.json +1356 -464
- package/schemas/evidence-artifact.schema.json +59 -29
- package/schemas/isolation-manifest.schema.json +17 -10
- package/schemas/probe.schema.json +197 -71
- package/schemas/rubric.schema.json +1 -1
- package/schemas/sealed-run-record.schema.json +296 -39
|
@@ -31,10 +31,11 @@ export type EnvironmentProbePort = {
|
|
|
31
31
|
};
|
|
32
32
|
/** the boundary parsers `application/` and the conformance suite validate with. */
|
|
33
33
|
export declare const probeParsers: {
|
|
34
|
-
readonly request: import("zod").ZodObject<{
|
|
34
|
+
readonly request: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
|
|
35
35
|
probeId: import("zod").ZodString;
|
|
36
36
|
interfaceId: import("zod").ZodString;
|
|
37
37
|
operationId: import("zod").ZodString;
|
|
38
|
+
kind: import("zod").ZodLiteral<"api">;
|
|
38
39
|
method: import("zod").ZodEnum<{
|
|
39
40
|
DELETE: "DELETE";
|
|
40
41
|
GET: "GET";
|
|
@@ -56,11 +57,33 @@ export declare const probeParsers: {
|
|
|
56
57
|
kind: import("zod").ZodLiteral<"absent">;
|
|
57
58
|
}, import("zod/v4/core").$strict>], "kind">;
|
|
58
59
|
}, import("zod/v4/core").$strict>;
|
|
59
|
-
}, import("zod/v4/core").$strict
|
|
60
|
-
readonly response: import("zod").ZodObject<{
|
|
60
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
61
61
|
probeId: import("zod").ZodString;
|
|
62
62
|
interfaceId: import("zod").ZodString;
|
|
63
63
|
operationId: import("zod").ZodString;
|
|
64
|
+
kind: import("zod").ZodLiteral<"cli">;
|
|
65
|
+
executable: import("zod").ZodString;
|
|
66
|
+
subcommandPath: import("zod").ZodArray<import("zod").ZodString>;
|
|
67
|
+
channels: import("zod").ZodObject<{
|
|
68
|
+
argument: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodType<import("../core/schemas/primitives.ts").JsonValue, unknown, import("zod/v4/core").$ZodTypeInternals<import("../core/schemas/primitives.ts").JsonValue, unknown>>>;
|
|
69
|
+
option: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodType<import("../core/schemas/primitives.ts").JsonValue, unknown, import("zod/v4/core").$ZodTypeInternals<import("../core/schemas/primitives.ts").JsonValue, unknown>>>;
|
|
70
|
+
environment: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>;
|
|
71
|
+
stdin: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
|
|
72
|
+
kind: import("zod").ZodLiteral<"json">;
|
|
73
|
+
value: import("zod").ZodType<import("../core/schemas/primitives.ts").JsonValue, unknown, import("zod/v4/core").$ZodTypeInternals<import("../core/schemas/primitives.ts").JsonValue, unknown>>;
|
|
74
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
75
|
+
kind: import("zod").ZodLiteral<"text">;
|
|
76
|
+
value: import("zod").ZodString;
|
|
77
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
78
|
+
kind: import("zod").ZodLiteral<"absent">;
|
|
79
|
+
}, import("zod/v4/core").$strict>], "kind">;
|
|
80
|
+
}, import("zod/v4/core").$strict>;
|
|
81
|
+
}, import("zod/v4/core").$strict>], "kind">;
|
|
82
|
+
readonly response: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
|
|
83
|
+
probeId: import("zod").ZodString;
|
|
84
|
+
interfaceId: import("zod").ZodString;
|
|
85
|
+
operationId: import("zod").ZodString;
|
|
86
|
+
kind: import("zod").ZodLiteral<"api">;
|
|
64
87
|
status: import("zod").ZodInt;
|
|
65
88
|
headers: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>;
|
|
66
89
|
body: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
|
|
@@ -72,5 +95,38 @@ export declare const probeParsers: {
|
|
|
72
95
|
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
73
96
|
kind: import("zod").ZodLiteral<"absent">;
|
|
74
97
|
}, import("zod/v4/core").$strict>], "kind">;
|
|
75
|
-
}, import("zod/v4/core").$strict
|
|
98
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
99
|
+
probeId: import("zod").ZodString;
|
|
100
|
+
interfaceId: import("zod").ZodString;
|
|
101
|
+
operationId: import("zod").ZodString;
|
|
102
|
+
kind: import("zod").ZodLiteral<"cli">;
|
|
103
|
+
exitCode: import("zod").ZodInt;
|
|
104
|
+
stdout: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
|
|
105
|
+
kind: import("zod").ZodLiteral<"json">;
|
|
106
|
+
value: import("zod").ZodType<import("../core/schemas/primitives.ts").JsonValue, unknown, import("zod/v4/core").$ZodTypeInternals<import("../core/schemas/primitives.ts").JsonValue, unknown>>;
|
|
107
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
108
|
+
kind: import("zod").ZodLiteral<"text">;
|
|
109
|
+
value: import("zod").ZodString;
|
|
110
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
111
|
+
kind: import("zod").ZodLiteral<"absent">;
|
|
112
|
+
}, import("zod/v4/core").$strict>], "kind">;
|
|
113
|
+
stderr: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
|
|
114
|
+
kind: import("zod").ZodLiteral<"json">;
|
|
115
|
+
value: import("zod").ZodType<import("../core/schemas/primitives.ts").JsonValue, unknown, import("zod/v4/core").$ZodTypeInternals<import("../core/schemas/primitives.ts").JsonValue, unknown>>;
|
|
116
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
117
|
+
kind: import("zod").ZodLiteral<"text">;
|
|
118
|
+
value: import("zod").ZodString;
|
|
119
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
120
|
+
kind: import("zod").ZodLiteral<"absent">;
|
|
121
|
+
}, import("zod/v4/core").$strict>], "kind">;
|
|
122
|
+
artifacts: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
|
|
123
|
+
kind: import("zod").ZodLiteral<"json">;
|
|
124
|
+
value: import("zod").ZodType<import("../core/schemas/primitives.ts").JsonValue, unknown, import("zod/v4/core").$ZodTypeInternals<import("../core/schemas/primitives.ts").JsonValue, unknown>>;
|
|
125
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
126
|
+
kind: import("zod").ZodLiteral<"text">;
|
|
127
|
+
value: import("zod").ZodString;
|
|
128
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
129
|
+
kind: import("zod").ZodLiteral<"absent">;
|
|
130
|
+
}, import("zod/v4/core").$strict>], "kind">>;
|
|
131
|
+
}, import("zod/v4/core").$strict>], "kind">;
|
|
76
132
|
};
|
|
@@ -6,6 +6,35 @@
|
|
|
6
6
|
* Each of the thirteen builds its own `'resolves'` subject and reads
|
|
7
7
|
* `underlyingCalls()` from a counter starting at zero, so every count below is
|
|
8
8
|
* absolute.
|
|
9
|
+
*
|
|
10
|
+
* **This suite certifies an adapter for the `api` mechanism and says nothing
|
|
11
|
+
* about the `cli` one.** Every scenario is HTTP: redirects, methods, schemes,
|
|
12
|
+
* an anomalous status. `ProbeSubject` requires an unauthorized-method request,
|
|
13
|
+
* a redirecting request and a not-found request, none of which a command
|
|
14
|
+
* adapter has. So an adapter that runs commands cannot present a subject here,
|
|
15
|
+
* and an adapter that passes all nineteen has been shown nothing about whether
|
|
16
|
+
* it can run one safely: it may deny an unmapped executable or execute a shell
|
|
17
|
+
* string, and this suite cannot tell the difference.
|
|
18
|
+
*
|
|
19
|
+
* That is a real gap in the published surface and it is wider than this suite.
|
|
20
|
+
* `ProbeTargetPolicy` has one authorization shape and every field in it is
|
|
21
|
+
* HTTP: scheme, host, port, resolved addresses, methods, safe methods,
|
|
22
|
+
* redirects, request and response byte caps. **A command interface cannot be
|
|
23
|
+
* authorized at all**, so AD-35's "an adapter denies by default and permits
|
|
24
|
+
* only what that mapping names" has nothing to name for the mechanism this
|
|
25
|
+
* release adds, and a conformance arm built on top of a policy that cannot
|
|
26
|
+
* express a command authorization would certify against nothing.
|
|
27
|
+
*
|
|
28
|
+
* Closing it is a declaration first and a suite second: a command
|
|
29
|
+
* authorization naming a permitted executable, the subcommand paths and
|
|
30
|
+
* environment keys it may carry, and its own elapsed and output-byte caps;
|
|
31
|
+
* then the denials to certify — an executable no mapping names, a refusal to
|
|
32
|
+
* accept a pre-built argument vector, a non-zero exit as an observation rather
|
|
33
|
+
* than a fault, each cap enforced. That is a design addition to the published
|
|
34
|
+
* surface rather than a repair, and it is not made here. Until it exists an
|
|
35
|
+
* adopter writing a command adapter has no policy to declare and no harness to
|
|
36
|
+
* run, and this comment is here so nobody concludes from a green run that they
|
|
37
|
+
* have either.
|
|
9
38
|
*/
|
|
10
39
|
import type { ProbeRequest } from '../core/schemas/port-messages.ts';
|
|
11
40
|
import type { ProbeTargetPolicy } from '../core/schemas/probe-policy.ts';
|
|
@@ -23,9 +23,9 @@ const PROBE_ASSERTIONS = [
|
|
|
23
23
|
request: (subject) => subject.faultingRequest,
|
|
24
24
|
expectation: {
|
|
25
25
|
kind: 'resolves',
|
|
26
|
-
check: (observation) => observation.status === 500
|
|
26
|
+
check: (observation) => observation.kind === 'api' && observation.status === 500
|
|
27
27
|
? undefined
|
|
28
|
-
: `observed status ${observation.status}, expected 500`,
|
|
28
|
+
: `observed ${observation.kind === 'api' ? `status ${observation.status}` : 'a command observation'}, expected status 500`,
|
|
29
29
|
},
|
|
30
30
|
},
|
|
31
31
|
{
|
|
@@ -114,14 +114,42 @@ const PROBE_ASSERTIONS = [
|
|
|
114
114
|
expectation: { kind: 'rejects', code: CAPPED },
|
|
115
115
|
},
|
|
116
116
|
];
|
|
117
|
-
function checkResolved(assertion, expectation, value) {
|
|
117
|
+
function checkResolved(assertion, expectation, value, request) {
|
|
118
118
|
const parsed = probeParsers.response.safeParse(value);
|
|
119
119
|
if (!parsed.success) {
|
|
120
120
|
return titledOutcome(assertion.id, assertion.title, false, 'the resolved value is not a schema-valid ProbeObservation');
|
|
121
121
|
}
|
|
122
|
+
// Schema validity is not correlation. Both messages are unions now, so an
|
|
123
|
+
// adapter can answer a command request with a schema-valid HTTP observation
|
|
124
|
+
// and satisfy every assertion below without running a command or consulting
|
|
125
|
+
// a policy. The four echoed fields are what tie one answer to one question,
|
|
126
|
+
// and `ProbeRequest.probeId`'s own description already says the port returns
|
|
127
|
+
// them unchanged.
|
|
128
|
+
const mismatch = echoMismatch(request, parsed.data);
|
|
129
|
+
if (mismatch !== undefined) {
|
|
130
|
+
return titledOutcome(assertion.id, assertion.title, false, mismatch);
|
|
131
|
+
}
|
|
122
132
|
const complaint = expectation.check?.(parsed.data);
|
|
123
133
|
return titledOutcome(assertion.id, assertion.title, complaint === undefined, complaint ?? '');
|
|
124
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Which of the four echoed fields the observation failed to return unchanged,
|
|
137
|
+
* or `undefined` when it answered the question it was asked.
|
|
138
|
+
*/
|
|
139
|
+
function echoMismatch(request, observation) {
|
|
140
|
+
const echoed = [
|
|
141
|
+
['kind', request.kind, observation.kind],
|
|
142
|
+
['probeId', request.probeId, observation.probeId],
|
|
143
|
+
['interfaceId', request.interfaceId, observation.interfaceId],
|
|
144
|
+
['operationId', request.operationId, observation.operationId],
|
|
145
|
+
];
|
|
146
|
+
for (const [field, asked, answered] of echoed) {
|
|
147
|
+
if (asked === answered)
|
|
148
|
+
continue;
|
|
149
|
+
return `observed ${field} "${answered}" for a request carrying "${asked}", so the answer does not correlate with the question`;
|
|
150
|
+
}
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
125
153
|
function checkRejected(assertion, expectedCode, error) {
|
|
126
154
|
const view = faultView(error);
|
|
127
155
|
if (view === undefined) {
|
|
@@ -153,12 +181,13 @@ async function runProbeAssertion(assertion, subject) {
|
|
|
153
181
|
if (!run.ok) {
|
|
154
182
|
return titledOutcome(assertion.id, assertion.title, false, run.detail);
|
|
155
183
|
}
|
|
156
|
-
const
|
|
184
|
+
const request = assertion.request(subject);
|
|
185
|
+
const settled = await settle(run.built.port(request, new AbortController().signal));
|
|
157
186
|
let result;
|
|
158
187
|
if (assertion.expectation.kind === 'resolves') {
|
|
159
188
|
result =
|
|
160
189
|
settled.kind === 'resolved'
|
|
161
|
-
? checkResolved(assertion, assertion.expectation, settled.value)
|
|
190
|
+
? checkResolved(assertion, assertion.expectation, settled.value, request)
|
|
162
191
|
: titledOutcome(assertion.id, assertion.title, false, `rejected with ${describeThrown(settled.error)} instead of returning an observation`);
|
|
163
192
|
}
|
|
164
193
|
else {
|
package/package.json
CHANGED