eval-quality 0.1.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/LICENSE +190 -0
- package/README.md +355 -0
- package/corpus/dev/README.md +36 -0
- package/corpus/dev/compile-seal-example/brief.json +1 -0
- package/corpus/dev/compile-seal-example/contract.json +1 -0
- package/corpus/dev/contracts/absent-collection-locations.json +1 -0
- package/corpus/dev/contracts/absent-sibling-groups.json +1 -0
- package/corpus/dev/contracts/absent-success-indicator.json +1 -0
- package/corpus/dev/contracts/empty-channel-roles.json +1 -0
- package/corpus/dev/contracts/empty-collection-locations.json +1 -0
- package/corpus/dev/contracts/empty-request-shapes.json +1 -0
- package/corpus/dev/contracts/empty-sibling-groups.json +1 -0
- package/corpus/dev/contracts/no-collection-quantifier.json +1 -0
- package/corpus/dev/contracts/no-operation-inventory.json +1 -0
- package/corpus/dev/contracts/no-read-back-relation.json +1 -0
- package/corpus/dev/contracts/no-state-change-marker.json +1 -0
- package/corpus/dev/contracts/no-type-violating-step.json +1 -0
- package/corpus/dev/contracts/per-key-split-oracles.json +1 -0
- package/corpus/dev/contracts/satisfied-declarations.json +1 -0
- package/corpus/dev/contracts/single-required-response-key.json +1 -0
- package/corpus/dev/contracts/split-indicator-oracle.json +1 -0
- package/corpus/dev/contracts/unaddressed-parameter-sibling.json +1 -0
- package/corpus/dev/contracts/unnamed-reference-set.json +1 -0
- package/corpus/dev/contracts/wrong-cardinality-form.json +1 -0
- package/corpus/dev/index.json +1 -0
- package/dist/adapters/index.d.ts +12 -0
- package/dist/adapters/index.js +3 -0
- package/dist/adapters/local-corpus-adapter.d.ts +7 -0
- package/dist/adapters/local-corpus-adapter.js +78 -0
- package/dist/adapters/node-file-system-adapter.d.ts +7 -0
- package/dist/adapters/node-file-system-adapter.js +39 -0
- package/dist/adapters/port-boundary.d.ts +18 -0
- package/dist/adapters/port-boundary.js +83 -0
- package/dist/adapters/system-clock-adapter.d.ts +10 -0
- package/dist/adapters/system-clock-adapter.js +18 -0
- package/dist/application/compile.d.ts +4 -0
- package/dist/application/compile.js +24 -0
- package/dist/application/diagnostics.d.ts +22 -0
- package/dist/application/diagnostics.js +18 -0
- package/dist/application/index.d.ts +23 -0
- package/dist/application/index.js +17 -0
- package/dist/application/invoke-port.d.ts +2 -0
- package/dist/application/invoke-port.js +45 -0
- package/dist/application/preflight.d.ts +27 -0
- package/dist/application/preflight.js +131 -0
- package/dist/application/seal.d.ts +4 -0
- package/dist/application/seal.js +28 -0
- package/dist/application/serialize.d.ts +6 -0
- package/dist/application/serialize.js +9 -0
- package/dist/cli/arguments.d.ts +28 -0
- package/dist/cli/arguments.js +167 -0
- package/dist/cli/exit-codes.d.ts +36 -0
- package/dist/cli/exit-codes.js +39 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +143 -0
- package/dist/cli/render.d.ts +26 -0
- package/dist/cli/render.js +53 -0
- package/dist/cli/run.d.ts +41 -0
- package/dist/cli/run.js +203 -0
- package/dist/core/canonical/canonicalize.d.ts +1 -0
- package/dist/core/canonical/canonicalize.js +113 -0
- package/dist/core/canonical/digest.d.ts +7 -0
- package/dist/core/canonical/digest.js +81 -0
- package/dist/core/canonical/scan-json.d.ts +1 -0
- package/dist/core/canonical/scan-json.js +298 -0
- package/dist/core/canonical/value-domain.d.ts +4 -0
- package/dist/core/canonical/value-domain.js +113 -0
- package/dist/core/compile/compile.d.ts +24 -0
- package/dist/core/compile/compile.js +67 -0
- package/dist/core/compile/declarations.d.ts +5 -0
- package/dist/core/compile/declarations.js +22 -0
- package/dist/core/compile/expression-legality.d.ts +14 -0
- package/dist/core/compile/expression-legality.js +346 -0
- package/dist/core/compile/forbidden-inputs.d.ts +5 -0
- package/dist/core/compile/forbidden-inputs.js +19 -0
- package/dist/core/compile/interface-inventory.d.ts +10 -0
- package/dist/core/compile/interface-inventory.js +55 -0
- package/dist/core/compile/oracle-alignment.d.ts +14 -0
- package/dist/core/compile/oracle-alignment.js +93 -0
- package/dist/core/compile/reachability.d.ts +17 -0
- package/dist/core/compile/reachability.js +177 -0
- package/dist/core/compile/rubrics.d.ts +55 -0
- package/dist/core/compile/rubrics.js +198 -0
- package/dist/core/compile/scripting-bound.d.ts +5 -0
- package/dist/core/compile/scripting-bound.js +151 -0
- package/dist/core/compile/sensitivity-witness.d.ts +73 -0
- package/dist/core/compile/sensitivity-witness.js +232 -0
- package/dist/core/compile/waivers.d.ts +3 -0
- package/dist/core/compile/waivers.js +21 -0
- package/dist/core/coverage/coverage.d.ts +18 -0
- package/dist/core/coverage/coverage.js +47 -0
- package/dist/core/coverage/relevance.d.ts +75 -0
- package/dist/core/coverage/relevance.js +186 -0
- package/dist/core/coverage/rules.d.ts +7 -0
- package/dist/core/coverage/rules.js +18 -0
- package/dist/core/coverage/satisfaction.d.ts +107 -0
- package/dist/core/coverage/satisfaction.js +415 -0
- package/dist/core/coverage/table.d.ts +26 -0
- package/dist/core/coverage/table.js +222 -0
- package/dist/core/declared-inputs.d.ts +16 -0
- package/dist/core/declared-inputs.js +18 -0
- package/dist/core/evaluate/evidence-resolution.d.ts +54 -0
- package/dist/core/evaluate/evidence-resolution.js +153 -0
- package/dist/core/evaluate/operators.d.ts +87 -0
- package/dist/core/evaluate/operators.js +350 -0
- package/dist/core/evaluate/resolution.d.ts +40 -0
- package/dist/core/evaluate/resolution.js +336 -0
- package/dist/core/evaluate/resolved-value.d.ts +9 -0
- package/dist/core/evaluate/resolved-value.js +6 -0
- package/dist/core/failure-codes.d.ts +18 -0
- package/dist/core/failure-codes.js +50 -0
- package/dist/core/lineage/chain.d.ts +49 -0
- package/dist/core/lineage/chain.js +210 -0
- package/dist/core/lineage/freeze.d.ts +12 -0
- package/dist/core/lineage/freeze.js +35 -0
- package/dist/core/lineage/stage-table.d.ts +43 -0
- package/dist/core/lineage/stage-table.js +106 -0
- package/dist/core/preflight/plan.d.ts +67 -0
- package/dist/core/preflight/plan.js +313 -0
- package/dist/core/preflight/projection.d.ts +40 -0
- package/dist/core/preflight/projection.js +96 -0
- package/dist/core/preflight/reduce.d.ts +8 -0
- package/dist/core/preflight/reduce.js +180 -0
- package/dist/core/preflight/witness-evidence.d.ts +42 -0
- package/dist/core/preflight/witness-evidence.js +88 -0
- package/dist/core/probe/target-policy.d.ts +63 -0
- package/dist/core/probe/target-policy.js +328 -0
- package/dist/core/schemas/artifact-reference.d.ts +19 -0
- package/dist/core/schemas/artifact-reference.js +30 -0
- package/dist/core/schemas/artifact.d.ts +1153 -0
- package/dist/core/schemas/artifact.js +84 -0
- package/dist/core/schemas/constraint-ledger.d.ts +57 -0
- package/dist/core/schemas/constraint-ledger.js +143 -0
- package/dist/core/schemas/eval-contract.d.ts +402 -0
- package/dist/core/schemas/eval-contract.js +147 -0
- package/dist/core/schemas/evaluator-configuration.d.ts +37 -0
- package/dist/core/schemas/evaluator-configuration.js +43 -0
- package/dist/core/schemas/evidence-artifact.d.ts +471 -0
- package/dist/core/schemas/evidence-artifact.js +232 -0
- package/dist/core/schemas/expression.d.ts +197 -0
- package/dist/core/schemas/expression.js +284 -0
- package/dist/core/schemas/faults.d.ts +9 -0
- package/dist/core/schemas/faults.js +32 -0
- package/dist/core/schemas/interface.d.ts +417 -0
- package/dist/core/schemas/interface.js +115 -0
- package/dist/core/schemas/isolation-manifest.d.ts +136 -0
- package/dist/core/schemas/isolation-manifest.js +92 -0
- package/dist/core/schemas/lineage.d.ts +21 -0
- package/dist/core/schemas/lineage.js +28 -0
- package/dist/core/schemas/oracle.d.ts +72 -0
- package/dist/core/schemas/oracle.js +35 -0
- package/dist/core/schemas/plan.d.ts +115 -0
- package/dist/core/schemas/plan.js +58 -0
- package/dist/core/schemas/pointer.d.ts +63 -0
- package/dist/core/schemas/pointer.js +94 -0
- package/dist/core/schemas/port-messages.d.ts +103 -0
- package/dist/core/schemas/port-messages.js +90 -0
- package/dist/core/schemas/preflight-verdict.d.ts +60 -0
- package/dist/core/schemas/preflight-verdict.js +38 -0
- package/dist/core/schemas/primitives.d.ts +78 -0
- package/dist/core/schemas/primitives.js +121 -0
- package/dist/core/schemas/private-artifact-manifest.d.ts +56 -0
- package/dist/core/schemas/private-artifact-manifest.js +46 -0
- package/dist/core/schemas/probe-body.d.ts +25 -0
- package/dist/core/schemas/probe-body.js +23 -0
- package/dist/core/schemas/probe-policy.d.ts +76 -0
- package/dist/core/schemas/probe-policy.js +33 -0
- package/dist/core/schemas/probe.d.ts +189 -0
- package/dist/core/schemas/probe.js +82 -0
- package/dist/core/schemas/publish.d.ts +30 -0
- package/dist/core/schemas/publish.js +135 -0
- package/dist/core/schemas/reference-set.d.ts +18 -0
- package/dist/core/schemas/reference-set.js +27 -0
- package/dist/core/schemas/rubric.d.ts +62 -0
- package/dist/core/schemas/rubric.js +68 -0
- package/dist/core/schemas/scoring-policy.d.ts +28 -0
- package/dist/core/schemas/scoring-policy.js +51 -0
- package/dist/core/schemas/sealed-evaluator-brief.d.ts +80 -0
- package/dist/core/schemas/sealed-evaluator-brief.js +59 -0
- package/dist/core/schemas/sealed-run-record.d.ts +382 -0
- package/dist/core/schemas/sealed-run-record.js +215 -0
- package/dist/core/schemas/sensitivity-witness.d.ts +138 -0
- package/dist/core/schemas/sensitivity-witness.js +86 -0
- package/dist/core/schemas/verdict.d.ts +25 -0
- package/dist/core/schemas/verdict.js +20 -0
- package/dist/core/schemas/waiver.d.ts +17 -0
- package/dist/core/schemas/waiver.js +24 -0
- package/dist/core/seal/derived-reference.d.ts +36 -0
- package/dist/core/seal/derived-reference.js +383 -0
- package/dist/core/seal/direction-prose.d.ts +13 -0
- package/dist/core/seal/direction-prose.js +120 -0
- package/dist/core/seal/plan-index.d.ts +63 -0
- package/dist/core/seal/plan-index.js +155 -0
- package/dist/core/seal/scripting-audit.d.ts +15 -0
- package/dist/core/seal/scripting-audit.js +51 -0
- package/dist/core/seal/seal.d.ts +18 -0
- package/dist/core/seal/seal.js +155 -0
- package/dist/core/stage-contracts.d.ts +30 -0
- package/dist/core/stage-contracts.js +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +22 -0
- package/dist/ports/clock-port.d.ts +13 -0
- package/dist/ports/clock-port.js +7 -0
- package/dist/ports/corpus-port.d.ts +16 -0
- package/dist/ports/corpus-port.js +7 -0
- package/dist/ports/environment-probe-port.d.ts +76 -0
- package/dist/ports/environment-probe-port.js +32 -0
- package/dist/ports/file-system-port.d.ts +27 -0
- package/dist/ports/file-system-port.js +11 -0
- package/dist/ports/port.d.ts +33 -0
- package/dist/ports/port.js +14 -0
- package/dist/testing/conformance.d.ts +88 -0
- package/dist/testing/conformance.js +281 -0
- package/dist/testing/index.d.ts +26 -0
- package/dist/testing/index.js +18 -0
- package/dist/testing/probe-conformance.d.ts +45 -0
- package/dist/testing/probe-conformance.js +186 -0
- package/package.json +130 -0
- package/schemas/artifact-reference.schema.json +64 -0
- package/schemas/eval-contract.schema.json +2145 -0
- package/schemas/evaluator-configuration.schema.json +199 -0
- package/schemas/evidence-artifact.schema.json +1229 -0
- package/schemas/isolation-manifest.schema.json +394 -0
- package/schemas/preflight-verdict.schema.json +114 -0
- package/schemas/private-artifact-manifest.schema.json +103 -0
- package/schemas/probe.schema.json +1151 -0
- package/schemas/rubric.schema.json +148 -0
- package/schemas/scoring-policy.schema.json +90 -0
- package/schemas/sealed-evaluator-brief.schema.json +268 -0
- package/schemas/sealed-run-record.schema.json +875 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { probeParsers } from '../ports/environment-probe-port.js';
|
|
2
|
+
import { buildScenario, countCalls, describeThrown, disposeScenario, faultView, reportOf, runSharedAssertions, settle, titledOutcome, withDispose, } from './conformance.js';
|
|
3
|
+
function authorizationFor(subject, request) {
|
|
4
|
+
return subject.policy.authorizations.find((each) => each.interfaceId === request.interfaceId);
|
|
5
|
+
}
|
|
6
|
+
const DENIED = 'forbidden-target';
|
|
7
|
+
const CAPPED = 'budget-exhausted';
|
|
8
|
+
const PROBE_ASSERTIONS = [
|
|
9
|
+
{
|
|
10
|
+
// Without this one, a subject that denies everything scores twelve of
|
|
11
|
+
// twelve on default-deny while being useless. AD-35 spends a clause on
|
|
12
|
+
// why a blanket loopback ban is wrong.
|
|
13
|
+
id: 'probe/allow-authorized-loopback',
|
|
14
|
+
title: 'an explicitly authorized target is reached and observed',
|
|
15
|
+
request: (subject) => subject.authorizedRequest,
|
|
16
|
+
expectation: { kind: 'resolves' },
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
// A subject that throws on 5xx fails here and nowhere else, and it makes
|
|
20
|
+
// AD-10's seeded-fault check unimplementable.
|
|
21
|
+
id: 'probe/observe-anomalous-status',
|
|
22
|
+
title: 'a 500 from an authorized target is an observation, not a fault',
|
|
23
|
+
request: (subject) => subject.faultingRequest,
|
|
24
|
+
expectation: {
|
|
25
|
+
kind: 'resolves',
|
|
26
|
+
check: (observation) => observation.status === 500
|
|
27
|
+
? undefined
|
|
28
|
+
: `observed status ${observation.status}, expected 500`,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 'probe/deny-unmapped-interface',
|
|
33
|
+
title: 'an interface the mapping does not name is refused before a packet leaves',
|
|
34
|
+
request: (subject) => subject.unmappedRequest,
|
|
35
|
+
expectation: { kind: 'rejects', code: DENIED },
|
|
36
|
+
expectedCalls: () => 0,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'probe/deny-unauthorized-loopback',
|
|
40
|
+
title: 'a loopback address no authorization names is denied',
|
|
41
|
+
request: (subject) => subject.deniedAddressRequests.loopback,
|
|
42
|
+
expectation: { kind: 'rejects', code: DENIED },
|
|
43
|
+
expectedCalls: () => 0,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: 'probe/deny-private',
|
|
47
|
+
title: 'a private RFC 1918 address is denied',
|
|
48
|
+
request: (subject) => subject.deniedAddressRequests.private,
|
|
49
|
+
expectation: { kind: 'rejects', code: DENIED },
|
|
50
|
+
expectedCalls: () => 0,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: 'probe/deny-link-local',
|
|
54
|
+
title: 'a link-local address is denied',
|
|
55
|
+
request: (subject) => subject.deniedAddressRequests.linkLocal,
|
|
56
|
+
expectation: { kind: 'rejects', code: DENIED },
|
|
57
|
+
expectedCalls: () => 0,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: 'probe/deny-metadata',
|
|
61
|
+
title: 'a cloud metadata address is denied',
|
|
62
|
+
request: (subject) => subject.deniedAddressRequests.metadata,
|
|
63
|
+
expectation: { kind: 'rejects', code: DENIED },
|
|
64
|
+
expectedCalls: () => 0,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'probe/deny-unauthorized-method',
|
|
68
|
+
title: 'a method the authorization does not list is denied',
|
|
69
|
+
request: (subject) => subject.unauthorizedMethodRequest,
|
|
70
|
+
expectation: { kind: 'rejects', code: DENIED },
|
|
71
|
+
expectedCalls: () => 0,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: 'probe/deny-unauthorized-scheme',
|
|
75
|
+
title: 'a scheme the authorization does not name is denied',
|
|
76
|
+
request: (subject) => subject.unauthorizedSchemeRequest,
|
|
77
|
+
expectation: { kind: 'rejects', code: DENIED },
|
|
78
|
+
expectedCalls: () => 0,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
// The first hop is authorized and happens. The redirect target is
|
|
82
|
+
// revalidated and refused, so the second hop never runs. An adapter that
|
|
83
|
+
// follows the redirect resolves, and fails here.
|
|
84
|
+
id: 'probe/deny-on-redirect',
|
|
85
|
+
title: 'a redirect to a denied target is revalidated and refused',
|
|
86
|
+
request: (subject) => subject.redirectingRequest,
|
|
87
|
+
expectation: { kind: 'rejects', code: DENIED },
|
|
88
|
+
expectedCalls: () => 1,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
// Every hop is authorized, so only the count can refuse it. That is the
|
|
92
|
+
// half `deny-on-redirect` cannot reach.
|
|
93
|
+
id: 'probe/cap-redirects',
|
|
94
|
+
title: 'a chain of authorized redirects past maxRedirects is capped',
|
|
95
|
+
request: (subject) => subject.overRedirectRequest,
|
|
96
|
+
expectation: { kind: 'rejects', code: CAPPED },
|
|
97
|
+
expectedCalls: (subject) => {
|
|
98
|
+
const authorization = authorizationFor(subject, subject.overRedirectRequest);
|
|
99
|
+
return authorization === undefined
|
|
100
|
+
? "the subject's policy names no authorization for overRedirectRequest.interfaceId, so maxRedirects is unknown"
|
|
101
|
+
: authorization.maxRedirects + 1;
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: 'probe/cap-response-bytes',
|
|
106
|
+
title: 'a response past maxResponseBytes is a cap, not a policy denial',
|
|
107
|
+
request: (subject) => subject.oversizeResponseRequest,
|
|
108
|
+
expectation: { kind: 'rejects', code: CAPPED },
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: 'probe/cap-elapsed',
|
|
112
|
+
title: 'a response past maxElapsedMs is a cap, not an abort',
|
|
113
|
+
request: (subject) => subject.slowRequest,
|
|
114
|
+
expectation: { kind: 'rejects', code: CAPPED },
|
|
115
|
+
},
|
|
116
|
+
];
|
|
117
|
+
function checkResolved(assertion, expectation, value) {
|
|
118
|
+
const parsed = probeParsers.response.safeParse(value);
|
|
119
|
+
if (!parsed.success) {
|
|
120
|
+
return titledOutcome(assertion.id, assertion.title, false, 'the resolved value is not a schema-valid ProbeObservation');
|
|
121
|
+
}
|
|
122
|
+
const complaint = expectation.check?.(parsed.data);
|
|
123
|
+
return titledOutcome(assertion.id, assertion.title, complaint === undefined, complaint ?? '');
|
|
124
|
+
}
|
|
125
|
+
function checkRejected(assertion, expectedCode, error) {
|
|
126
|
+
const view = faultView(error);
|
|
127
|
+
if (view === undefined) {
|
|
128
|
+
return titledOutcome(assertion.id, assertion.title, false, `rejected with ${describeThrown(error)}, which carries no declared AD-28 code`);
|
|
129
|
+
}
|
|
130
|
+
return titledOutcome(assertion.id, assertion.title, view.code === expectedCode, `rejected with code "${view.code}", expected "${expectedCode}"`);
|
|
131
|
+
}
|
|
132
|
+
function checkCalls(assertion, subject, built, base) {
|
|
133
|
+
if (assertion.expectedCalls === undefined)
|
|
134
|
+
return base;
|
|
135
|
+
const expected = assertion.expectedCalls(subject);
|
|
136
|
+
if (typeof expected === 'string') {
|
|
137
|
+
return { ...base, passed: false, detail: expected };
|
|
138
|
+
}
|
|
139
|
+
const actual = countCalls(built);
|
|
140
|
+
if (typeof actual === 'string') {
|
|
141
|
+
return { ...base, passed: false, detail: actual };
|
|
142
|
+
}
|
|
143
|
+
if (actual === expected)
|
|
144
|
+
return base;
|
|
145
|
+
return {
|
|
146
|
+
...base,
|
|
147
|
+
passed: false,
|
|
148
|
+
detail: `${base.passed ? '' : `${base.detail}; `}underlyingCalls() was ${actual}, expected ${expected}`,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
async function runProbeAssertion(assertion, subject) {
|
|
152
|
+
const run = await buildScenario(subject, 'resolves');
|
|
153
|
+
if (!run.ok) {
|
|
154
|
+
return titledOutcome(assertion.id, assertion.title, false, run.detail);
|
|
155
|
+
}
|
|
156
|
+
const settled = await settle(run.built.port(assertion.request(subject), new AbortController().signal));
|
|
157
|
+
let result;
|
|
158
|
+
if (assertion.expectation.kind === 'resolves') {
|
|
159
|
+
result =
|
|
160
|
+
settled.kind === 'resolved'
|
|
161
|
+
? checkResolved(assertion, assertion.expectation, settled.value)
|
|
162
|
+
: titledOutcome(assertion.id, assertion.title, false, `rejected with ${describeThrown(settled.error)} instead of returning an observation`);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
result =
|
|
166
|
+
settled.kind === 'rejected'
|
|
167
|
+
? checkRejected(assertion, assertion.expectation.code, settled.error)
|
|
168
|
+
: titledOutcome(assertion.id, assertion.title, false, `resolved instead of rejecting with "${assertion.expectation.code}"`);
|
|
169
|
+
}
|
|
170
|
+
result = checkCalls(assertion, subject, run.built, result);
|
|
171
|
+
return withDispose(result, await disposeScenario(run.built));
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Nineteen outcomes: the six shared assertions plus AD-35's thirteen.
|
|
175
|
+
* `maxRequestBytes` is the one cap with no assertion; the request shape is the
|
|
176
|
+
* suite's own, so the suite cannot make a subject emit an oversize request. It
|
|
177
|
+
* stays declared and adapter-enforced.
|
|
178
|
+
*/
|
|
179
|
+
export async function runEnvironmentProbePortConformance(subject) {
|
|
180
|
+
const shared = await runSharedAssertions('probe', subject, probeParsers.response);
|
|
181
|
+
const additional = [];
|
|
182
|
+
for (const assertion of PROBE_ASSERTIONS) {
|
|
183
|
+
additional.push(await runProbeAssertion(assertion, subject));
|
|
184
|
+
}
|
|
185
|
+
return reportOf(subject.name, 'environment-probe', [...shared, ...additional]);
|
|
186
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "eval-quality",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Compile disciplined Behavioral Evaluation Contracts and score their ability to catch known defects.",
|
|
5
|
+
"author": "Murat Ozcan",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"private": false,
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"module": "dist/index.js",
|
|
10
|
+
"types": "dist/index.d.ts",
|
|
11
|
+
"bin": {
|
|
12
|
+
"eval-quality": "dist/cli/main.js"
|
|
13
|
+
},
|
|
14
|
+
"type": "module",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"eval",
|
|
17
|
+
"evals",
|
|
18
|
+
"evaluation",
|
|
19
|
+
"agent",
|
|
20
|
+
"agent-eval",
|
|
21
|
+
"llm",
|
|
22
|
+
"behavioral-contract",
|
|
23
|
+
"oracle",
|
|
24
|
+
"contract-strength",
|
|
25
|
+
"testing",
|
|
26
|
+
"ai"
|
|
27
|
+
],
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"schemas",
|
|
31
|
+
"corpus",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"exports": {
|
|
36
|
+
".": {
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"default": "./dist/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./adapters": {
|
|
41
|
+
"types": "./dist/adapters/index.d.ts",
|
|
42
|
+
"default": "./dist/adapters/index.js"
|
|
43
|
+
},
|
|
44
|
+
"./conformance": {
|
|
45
|
+
"types": "./dist/testing/index.d.ts",
|
|
46
|
+
"default": "./dist/testing/index.js"
|
|
47
|
+
},
|
|
48
|
+
"./schemas/*": "./schemas/*",
|
|
49
|
+
"./corpus/*": "./corpus/*",
|
|
50
|
+
"./package.json": "./package.json"
|
|
51
|
+
},
|
|
52
|
+
"homepage": "https://github.com/bmad-code-org/bmad-eval-quality#readme",
|
|
53
|
+
"repository": {
|
|
54
|
+
"type": "git",
|
|
55
|
+
"url": "git+https://github.com/bmad-code-org/bmad-eval-quality.git"
|
|
56
|
+
},
|
|
57
|
+
"bugs": {
|
|
58
|
+
"url": "https://github.com/bmad-code-org/bmad-eval-quality/issues"
|
|
59
|
+
},
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
},
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=22.20.0"
|
|
65
|
+
},
|
|
66
|
+
"scripts": {
|
|
67
|
+
"hooks:install": "husky",
|
|
68
|
+
"build": "tsc -p tsconfig-build.json",
|
|
69
|
+
"clean": "rm -rf dist",
|
|
70
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
71
|
+
"lint": "biome check .",
|
|
72
|
+
"lint:fix": "biome check --write .",
|
|
73
|
+
"format": "biome format --write .",
|
|
74
|
+
"check:docs": "node scripts/check-docs.mjs",
|
|
75
|
+
"check:doc-invocations": "node scripts/check-doc-invocations.mjs",
|
|
76
|
+
"lint:spine": "python3 scripts/spine-lint/lint_spine.py --registry-ad 5 --workspace-root . --fail-on high",
|
|
77
|
+
"test:spine-lint": "uv run --with pytest pytest scripts/spine-lint/tests -q",
|
|
78
|
+
"build:shareable": "node scripts/build-shareable.mjs",
|
|
79
|
+
"test": "vitest run",
|
|
80
|
+
"test:coverage": "vitest run --coverage",
|
|
81
|
+
"test:conformance": "npm run build && vitest run tests/adapters tests/testing tests/conformance",
|
|
82
|
+
"test:watch": "vitest",
|
|
83
|
+
"check:vectors": "python3 tests/fixtures/derive_vectors.py --check",
|
|
84
|
+
"generate:schemas": "node scripts/generate-schemas.ts",
|
|
85
|
+
"check:schemas": "node scripts/check-schemas.ts",
|
|
86
|
+
"check:ad5-registry": "node scripts/check-ad5-registry.ts",
|
|
87
|
+
"check:ad28-registry": "node scripts/check-ad28-registry.ts",
|
|
88
|
+
"generate:ad31-table": "node scripts/generate-ad31-table.ts",
|
|
89
|
+
"check:ad31-table": "node scripts/check-ad31-table.ts",
|
|
90
|
+
"check:layers": "node scripts/check-dependency-direction.ts",
|
|
91
|
+
"check:lineage": "node scripts/check-lineage-ownership.ts",
|
|
92
|
+
"check:boundary": "node scripts/check-package-boundary.ts",
|
|
93
|
+
"generate:dev-corpus": "node scripts/generate-dev-corpus.ts",
|
|
94
|
+
"check:corpus": "node scripts/check-dev-corpus.ts",
|
|
95
|
+
"check:website-deps": "node scripts/audit-lockfile-age.mjs --lockfile website/package-lock.json && node scripts/check-licenses.mjs --lockfile website/package-lock.json",
|
|
96
|
+
"check:shareable": "node scripts/check-shareable.mjs",
|
|
97
|
+
"bench:digest": "node scripts/bench-digest.ts",
|
|
98
|
+
"docs:dev": "npm --prefix website run dev",
|
|
99
|
+
"docs:build": "node tools/build-docs.mjs",
|
|
100
|
+
"docs:preview": "npm --prefix website run preview",
|
|
101
|
+
"docs:validate-links": "node tools/validate-doc-links.js",
|
|
102
|
+
"release:prepare": "node scripts/release-prepare.mjs",
|
|
103
|
+
"release:publish": "gh workflow run publish.yml --ref main",
|
|
104
|
+
"validate": "npm run build && npm run typecheck && npm run lint && npm run check:docs && npm run check:doc-invocations && npm run check:shareable && npm run lint:spine && npm run check:vectors && npm run check:schemas && npm run check:ad5-registry && npm run check:ad28-registry && npm run check:ad31-table && npm run check:layers && npm run check:lineage && npm run check:boundary && npm run check:corpus && npm run check:website-deps && npm run test:coverage",
|
|
105
|
+
"prepack": "npm run clean && npm run build",
|
|
106
|
+
"prepublishOnly": "node scripts/assert-publish-authorized.mjs"
|
|
107
|
+
},
|
|
108
|
+
"dependencies": {
|
|
109
|
+
"zod": "4.4.3"
|
|
110
|
+
},
|
|
111
|
+
"devDependencies": {
|
|
112
|
+
"@biomejs/biome": "2.5.10",
|
|
113
|
+
"@types/node": "22.20.1",
|
|
114
|
+
"@vitest/coverage-v8": "4.1.11",
|
|
115
|
+
"ajv": "8.20.0",
|
|
116
|
+
"husky": "9.1.7",
|
|
117
|
+
"lint-staged": "16.4.0",
|
|
118
|
+
"marked": "18.0.10",
|
|
119
|
+
"typescript": "7.0.2",
|
|
120
|
+
"vitest": "4.1.11"
|
|
121
|
+
},
|
|
122
|
+
"overrides": {
|
|
123
|
+
"vite": "7.3.6"
|
|
124
|
+
},
|
|
125
|
+
"lint-staged": {
|
|
126
|
+
"*.{ts,js,json}": [
|
|
127
|
+
"biome check --write --no-errors-on-unmatched"
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "urn:eval-quality:schema:artifact-reference",
|
|
4
|
+
"oneOf": [
|
|
5
|
+
{
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"storage": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"const": "public"
|
|
11
|
+
},
|
|
12
|
+
"path": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"minLength": 1
|
|
15
|
+
},
|
|
16
|
+
"privateRef": {
|
|
17
|
+
"type": "null"
|
|
18
|
+
},
|
|
19
|
+
"digest": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"pattern": "^sha256:[0-9a-f]{64}$",
|
|
22
|
+
"description": "AD-27 digest: \"sha256:\" plus 64 lowercase hexadecimal characters."
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"required": [
|
|
26
|
+
"storage",
|
|
27
|
+
"path",
|
|
28
|
+
"privateRef",
|
|
29
|
+
"digest"
|
|
30
|
+
],
|
|
31
|
+
"additionalProperties": false
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"type": "object",
|
|
35
|
+
"properties": {
|
|
36
|
+
"storage": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"const": "private"
|
|
39
|
+
},
|
|
40
|
+
"path": {
|
|
41
|
+
"type": "null"
|
|
42
|
+
},
|
|
43
|
+
"privateRef": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"minLength": 1,
|
|
46
|
+
"description": "An opaque handle resolved through the corpus port under AD-8, never a filesystem path and never a URL. AD-18 forbids a private path from entering any artifact, and this is the field a caller would otherwise reach for."
|
|
47
|
+
},
|
|
48
|
+
"digest": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"pattern": "^sha256:[0-9a-f]{64}$",
|
|
51
|
+
"description": "AD-27 digest: \"sha256:\" plus 64 lowercase hexadecimal characters."
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"required": [
|
|
55
|
+
"storage",
|
|
56
|
+
"path",
|
|
57
|
+
"privateRef",
|
|
58
|
+
"digest"
|
|
59
|
+
],
|
|
60
|
+
"additionalProperties": false
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"description": "A reference to an artifact, public by path or private by opaque handle. Succeeds the prior-art `artifact-ref` schema per AD-24, with its two `if`/`then` branches re-expressed as a discriminated union per AD-13 and its `sha256` field renamed to `digest` against the shared AD-27 primitive. Alone among the twelve interchange artifacts this one carries NO `schemaVersion` and NO AD-29 lineage: it is a reference shape embedded inside other artifacts rather than one that crosses the package boundary alone, so versioning it would add a key to every finding and every manifest entry for no reader. It is in the inventory because it is published, not because it is exchanged; the exemption is asserted by a test against the registry's `carriesLineage` flag."
|
|
64
|
+
}
|