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.
Files changed (125) hide show
  1. package/README.md +3 -3
  2. package/corpus/dev/README.md +3 -2
  3. package/corpus/dev/compile-seal-example/brief.json +1 -1
  4. package/corpus/dev/compile-seal-example/contract.json +1 -1
  5. package/corpus/dev/contracts/absent-collection-locations.json +1 -1
  6. package/corpus/dev/contracts/absent-sibling-groups.json +1 -1
  7. package/corpus/dev/contracts/absent-success-indicator.json +1 -1
  8. package/corpus/dev/contracts/empty-channel-roles.json +1 -1
  9. package/corpus/dev/contracts/empty-collection-locations.json +1 -1
  10. package/corpus/dev/contracts/empty-request-shapes.json +1 -1
  11. package/corpus/dev/contracts/empty-sibling-groups.json +1 -1
  12. package/corpus/dev/contracts/fragment-selection.json +1 -0
  13. package/corpus/dev/contracts/no-collection-quantifier.json +1 -1
  14. package/corpus/dev/contracts/no-operation-inventory.json +1 -1
  15. package/corpus/dev/contracts/no-read-back-relation.json +1 -1
  16. package/corpus/dev/contracts/no-state-change-marker.json +1 -1
  17. package/corpus/dev/contracts/no-type-violating-step.json +1 -1
  18. package/corpus/dev/contracts/per-key-split-oracles.json +1 -1
  19. package/corpus/dev/contracts/review-corpus.json +1 -0
  20. package/corpus/dev/contracts/satisfied-declarations.json +1 -1
  21. package/corpus/dev/contracts/single-required-response-key.json +1 -1
  22. package/corpus/dev/contracts/split-indicator-oracle.json +1 -1
  23. package/corpus/dev/contracts/unaddressed-parameter-sibling.json +1 -1
  24. package/corpus/dev/contracts/unnamed-reference-set.json +1 -1
  25. package/corpus/dev/contracts/wrong-cardinality-form.json +1 -1
  26. package/corpus/dev/index.json +1 -1
  27. package/dist/cli/render.d.ts +2 -5
  28. package/dist/cli/render.js +51 -1
  29. package/dist/core/compile/bindings.d.ts +26 -7
  30. package/dist/core/compile/bindings.js +49 -32
  31. package/dist/core/compile/compile.d.ts +12 -0
  32. package/dist/core/compile/compile.js +28 -1
  33. package/dist/core/compile/excluded-content.d.ts +11 -0
  34. package/dist/core/compile/excluded-content.js +42 -0
  35. package/dist/core/compile/expression-legality.d.ts +2 -2
  36. package/dist/core/compile/expression-legality.js +58 -12
  37. package/dist/core/compile/interface-inventory.d.ts +34 -1
  38. package/dist/core/compile/interface-inventory.js +88 -11
  39. package/dist/core/compile/reachability.d.ts +12 -2
  40. package/dist/core/compile/reachability.js +123 -36
  41. package/dist/core/compile/schema-version.d.ts +2 -0
  42. package/dist/core/compile/schema-version.js +25 -0
  43. package/dist/core/compile/sensitivity-witness.d.ts +31 -12
  44. package/dist/core/compile/sensitivity-witness.js +110 -23
  45. package/dist/core/compile/step-reference.d.ts +2 -0
  46. package/dist/core/compile/step-reference.js +49 -0
  47. package/dist/core/coverage/operations.d.ts +62 -0
  48. package/dist/core/coverage/operations.js +57 -0
  49. package/dist/core/coverage/relevance.d.ts +4 -2
  50. package/dist/core/coverage/relevance.js +22 -23
  51. package/dist/core/coverage/satisfaction.d.ts +2 -2
  52. package/dist/core/coverage/satisfaction.js +73 -48
  53. package/dist/core/declared-inputs.d.ts +83 -4
  54. package/dist/core/declared-inputs.js +105 -8
  55. package/dist/core/evaluate/evidence-resolution.d.ts +9 -12
  56. package/dist/core/evaluate/evidence-resolution.js +70 -10
  57. package/dist/core/evaluate/operators.d.ts +22 -0
  58. package/dist/core/evaluate/operators.js +17 -1
  59. package/dist/core/evaluate/resolution.d.ts +14 -3
  60. package/dist/core/evaluate/resolution.js +63 -3
  61. package/dist/core/excluded-content.d.ts +65 -0
  62. package/dist/core/excluded-content.js +113 -0
  63. package/dist/core/failure-codes.d.ts +2 -2
  64. package/dist/core/failure-codes.js +5 -2
  65. package/dist/core/ingest/conditions.d.ts +1 -1
  66. package/dist/core/ingest/ingest.js +8 -0
  67. package/dist/core/preflight/plan.d.ts +7 -5
  68. package/dist/core/preflight/plan.js +75 -32
  69. package/dist/core/preflight/projection.d.ts +6 -3
  70. package/dist/core/preflight/projection.js +22 -2
  71. package/dist/core/preflight/reduce.js +47 -7
  72. package/dist/core/preflight/witness-evidence.d.ts +5 -5
  73. package/dist/core/preflight/witness-evidence.js +63 -20
  74. package/dist/core/schemas/artifact.d.ts +683 -35
  75. package/dist/core/schemas/constraint-ledger.js +11 -0
  76. package/dist/core/schemas/defect-signature.d.ts +438 -16
  77. package/dist/core/schemas/defect-signature.js +58 -10
  78. package/dist/core/schemas/eval-contract.d.ts +517 -12
  79. package/dist/core/schemas/eval-contract.js +18 -2
  80. package/dist/core/schemas/evidence-artifact.d.ts +14 -4
  81. package/dist/core/schemas/evidence-artifact.js +1 -1
  82. package/dist/core/schemas/interface.d.ts +741 -13
  83. package/dist/core/schemas/interface.js +120 -7
  84. package/dist/core/schemas/isolation-manifest.js +16 -9
  85. package/dist/core/schemas/plan.d.ts +217 -3
  86. package/dist/core/schemas/plan.js +22 -1
  87. package/dist/core/schemas/pointer.d.ts +47 -1
  88. package/dist/core/schemas/pointer.js +89 -8
  89. package/dist/core/schemas/port-messages.d.ts +194 -10
  90. package/dist/core/schemas/port-messages.js +73 -6
  91. package/dist/core/schemas/probe-body.d.ts +18 -0
  92. package/dist/core/schemas/probe-body.js +13 -0
  93. package/dist/core/schemas/probe.d.ts +122 -3
  94. package/dist/core/schemas/probe.js +1 -1
  95. package/dist/core/schemas/sealed-run-record.d.ts +131 -9
  96. package/dist/core/schemas/sealed-run-record.js +56 -11
  97. package/dist/core/schemas/sensitivity-witness.d.ts +108 -6
  98. package/dist/core/schemas/sensitivity-witness.js +61 -5
  99. package/dist/core/score/bindings.d.ts +2 -2
  100. package/dist/core/score/bindings.js +25 -13
  101. package/dist/core/score/qualification.d.ts +5 -5
  102. package/dist/core/score/qualification.js +67 -37
  103. package/dist/core/score/quotation.d.ts +1 -24
  104. package/dist/core/score/quotation.js +29 -4
  105. package/dist/core/score/score.js +28 -2
  106. package/dist/core/score/strength.d.ts +9 -0
  107. package/dist/core/score/strength.js +35 -1
  108. package/dist/core/score/witness.d.ts +21 -0
  109. package/dist/core/score/witness.js +9 -4
  110. package/dist/core/seal/derived-reference.d.ts +2 -9
  111. package/dist/core/seal/derived-reference.js +62 -23
  112. package/dist/core/seal/plan-index.d.ts +18 -3
  113. package/dist/core/seal/plan-index.js +44 -8
  114. package/dist/index.d.ts +1 -1
  115. package/dist/index.js +1 -1
  116. package/dist/ports/environment-probe-port.d.ts +60 -4
  117. package/dist/testing/probe-conformance.d.ts +29 -0
  118. package/dist/testing/probe-conformance.js +34 -5
  119. package/package.json +1 -1
  120. package/schemas/eval-contract.schema.json +1356 -464
  121. package/schemas/evidence-artifact.schema.json +59 -29
  122. package/schemas/isolation-manifest.schema.json +17 -10
  123. package/schemas/probe.schema.json +197 -71
  124. package/schemas/rubric.schema.json +1 -1
  125. 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 settled = await settle(run.built.port(assertion.request(subject), new AbortController().signal));
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eval-quality",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Compile disciplined Behavioral Evaluation Contracts and score their ability to catch known defects.",
5
5
  "author": "Murat Ozcan",
6
6
  "license": "Apache-2.0",