eval-quality 0.1.0 → 0.2.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 (133) hide show
  1. package/README.md +142 -67
  2. package/corpus/dev/README.md +17 -11
  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/no-collection-quantifier.json +1 -1
  13. package/corpus/dev/contracts/no-operation-inventory.json +1 -1
  14. package/corpus/dev/contracts/no-read-back-relation.json +1 -1
  15. package/corpus/dev/contracts/no-state-change-marker.json +1 -1
  16. package/corpus/dev/contracts/no-type-violating-step.json +1 -1
  17. package/corpus/dev/contracts/per-key-split-oracles.json +1 -1
  18. package/corpus/dev/contracts/satisfied-declarations.json +1 -1
  19. package/corpus/dev/contracts/single-required-response-key.json +1 -1
  20. package/corpus/dev/contracts/split-indicator-oracle.json +1 -1
  21. package/corpus/dev/contracts/unaddressed-parameter-sibling.json +1 -1
  22. package/corpus/dev/contracts/unnamed-reference-set.json +1 -1
  23. package/corpus/dev/contracts/wrong-cardinality-form.json +1 -1
  24. package/corpus/dev/index.json +1 -1
  25. package/dist/application/index.d.ts +2 -0
  26. package/dist/application/index.js +1 -0
  27. package/dist/application/score.d.ts +48 -0
  28. package/dist/application/score.js +186 -0
  29. package/dist/cli/arguments.d.ts +7 -3
  30. package/dist/cli/arguments.js +73 -5
  31. package/dist/cli/exit-codes.d.ts +6 -2
  32. package/dist/cli/exit-codes.js +8 -9
  33. package/dist/cli/main.js +9 -0
  34. package/dist/cli/render.d.ts +1 -1
  35. package/dist/cli/render.js +6 -4
  36. package/dist/cli/run.d.ts +13 -3
  37. package/dist/cli/run.js +136 -16
  38. package/dist/core/canonical/canonicalize.d.ts +12 -0
  39. package/dist/core/canonical/canonicalize.js +18 -4
  40. package/dist/core/compile/bindings.d.ts +70 -0
  41. package/dist/core/compile/bindings.js +317 -0
  42. package/dist/core/compile/compile.d.ts +5 -0
  43. package/dist/core/compile/compile.js +9 -0
  44. package/dist/core/compile/expression-legality.d.ts +49 -0
  45. package/dist/core/compile/expression-legality.js +105 -31
  46. package/dist/core/compile/forbidden-inputs.d.ts +8 -1
  47. package/dist/core/compile/forbidden-inputs.js +16 -3
  48. package/dist/core/compile/interface-inventory.d.ts +23 -1
  49. package/dist/core/compile/interface-inventory.js +32 -3
  50. package/dist/core/compile/reachability.d.ts +18 -1
  51. package/dist/core/compile/reachability.js +46 -1
  52. package/dist/core/compile/sensitivity-witness.d.ts +1 -1
  53. package/dist/core/compile/sensitivity-witness.js +1 -1
  54. package/dist/core/emit/emit.d.ts +9 -0
  55. package/dist/core/emit/emit.js +214 -0
  56. package/dist/core/emit/private-artifact-digest.d.ts +11 -0
  57. package/dist/core/emit/private-artifact-digest.js +31 -0
  58. package/dist/core/evaluate/evidence-resolution.d.ts +11 -1
  59. package/dist/core/evaluate/evidence-resolution.js +4 -1
  60. package/dist/core/failure-codes.d.ts +2 -2
  61. package/dist/core/failure-codes.js +4 -2
  62. package/dist/core/ingest/conditions.d.ts +201 -0
  63. package/dist/core/ingest/conditions.js +48 -0
  64. package/dist/core/ingest/index.d.ts +13 -0
  65. package/dist/core/ingest/index.js +11 -0
  66. package/dist/core/ingest/ingest.d.ts +68 -0
  67. package/dist/core/ingest/ingest.js +310 -0
  68. package/dist/core/lineage/stage-table.d.ts +21 -4
  69. package/dist/core/lineage/stage-table.js +35 -3
  70. package/dist/core/preflight/witness-evidence.js +10 -0
  71. package/dist/core/schemas/artifact.d.ts +385 -14
  72. package/dist/core/schemas/constraint-ledger.js +40 -0
  73. package/dist/core/schemas/defect-signature.d.ts +273 -0
  74. package/dist/core/schemas/defect-signature.js +127 -0
  75. package/dist/core/schemas/eval-contract.d.ts +33 -0
  76. package/dist/core/schemas/eval-contract.js +14 -0
  77. package/dist/core/schemas/evidence-artifact.d.ts +99 -19
  78. package/dist/core/schemas/evidence-artifact.js +64 -8
  79. package/dist/core/schemas/plan.d.ts +112 -0
  80. package/dist/core/schemas/plan.js +67 -2
  81. package/dist/core/schemas/probe-qualification.d.ts +168 -0
  82. package/dist/core/schemas/probe-qualification.js +106 -0
  83. package/dist/core/schemas/probe.d.ts +312 -0
  84. package/dist/core/schemas/probe.js +6 -2
  85. package/dist/core/schemas/scoring-policy.d.ts +1 -0
  86. package/dist/core/schemas/scoring-policy.js +6 -1
  87. package/dist/core/schemas/sealed-evaluator-brief.d.ts +1 -0
  88. package/dist/core/schemas/sealed-evaluator-brief.js +4 -1
  89. package/dist/core/schemas/sealed-run-record.d.ts +30 -3
  90. package/dist/core/schemas/sealed-run-record.js +37 -5
  91. package/dist/core/score/binding-order.d.ts +31 -0
  92. package/dist/core/score/binding-order.js +88 -0
  93. package/dist/core/score/bindings.d.ts +93 -0
  94. package/dist/core/score/bindings.js +297 -0
  95. package/dist/core/score/ladder-table.d.ts +23 -0
  96. package/dist/core/score/ladder-table.js +109 -0
  97. package/dist/core/score/ladder.d.ts +229 -0
  98. package/dist/core/score/ladder.js +464 -0
  99. package/dist/core/score/mode-agreement.d.ts +30 -0
  100. package/dist/core/score/mode-agreement.js +16 -0
  101. package/dist/core/score/outcome-table.d.ts +17 -0
  102. package/dist/core/score/outcome-table.js +172 -0
  103. package/dist/core/score/outcome.d.ts +466 -0
  104. package/dist/core/score/outcome.js +562 -0
  105. package/dist/core/score/qualification.d.ts +83 -0
  106. package/dist/core/score/qualification.js +615 -0
  107. package/dist/core/score/quotation.d.ts +79 -0
  108. package/dist/core/score/quotation.js +201 -0
  109. package/dist/core/score/reduce-trials.d.ts +80 -0
  110. package/dist/core/score/reduce-trials.js +90 -0
  111. package/dist/core/score/score.d.ts +72 -0
  112. package/dist/core/score/score.js +581 -0
  113. package/dist/core/score/selection.d.ts +80 -0
  114. package/dist/core/score/selection.js +98 -0
  115. package/dist/core/score/strength.d.ts +49 -0
  116. package/dist/core/score/strength.js +193 -0
  117. package/dist/core/score/witness.d.ts +117 -0
  118. package/dist/core/score/witness.js +315 -0
  119. package/dist/core/seal/derived-reference.d.ts +1 -1
  120. package/dist/core/seal/derived-reference.js +236 -28
  121. package/dist/core/seal/seal.js +8 -3
  122. package/dist/core/stage-contracts.d.ts +62 -2
  123. package/dist/index.d.ts +1 -1
  124. package/dist/index.js +1 -1
  125. package/dist/testing/index.d.ts +2 -0
  126. package/dist/testing/index.js +1 -0
  127. package/package.json +12 -3
  128. package/schemas/eval-contract.schema.json +100 -2
  129. package/schemas/evidence-artifact.schema.json +96 -9
  130. package/schemas/probe.schema.json +508 -3
  131. package/schemas/scoring-policy.schema.json +8 -1
  132. package/schemas/sealed-evaluator-brief.schema.json +11 -1
  133. package/schemas/sealed-run-record.schema.json +19 -2
@@ -0,0 +1,273 @@
1
+ /** AD-40's machine-readable defect signature and its probe-side selector. */
2
+ import { z } from 'zod';
3
+ import { Expression } from './expression.ts';
4
+ /**
5
+ * The reserved step identifier every pointer in a discriminating condition is
6
+ * rooted at. AD-40 requires the predicate to be rooted at the selected
7
+ * observation rather than at a step identifier, and the shipped `Expression`
8
+ * addresses evidence only through an interaction-rooted pointer, so the
9
+ * signature spends one fixed word instead of minting a fourth pointer grammar:
10
+ *
11
+ * /interactions/observed/response-status
12
+ * /interactions/observed/response-body/error/code
13
+ *
14
+ * A fixed word, so no contract-local choice reaches the corpus, and the gate
15
+ * checks contract-independence instead of asserting it. Evaluation is the
16
+ * shipped path with no adapter: build the resolver map with exactly this one
17
+ * key, and resolve.
18
+ *
19
+ * `observed` is a legal `Identifier` and nothing reserves it, so a contract may
20
+ * declare a step by that name. The design is safe because the resolver map is
21
+ * built fresh with exactly one key and is never merged with a plan's
22
+ * observations. That is a stated invariant of this module;
23
+ * `compile/sensitivity-witness.ts` guards the same collision one level in.
24
+ */
25
+ export declare const OBSERVED_STEP_ID = "observed";
26
+ /**
27
+ * The probe-side binding value: `{ literal }` and `{ matcher }` only.
28
+ *
29
+ * Deliberately its own union rather than a reuse of `BindingValue`, which also
30
+ * admits `{ captured }` and `{ principal }`. A captured pointer names an
31
+ * earlier step of a contract's plan, and a principal names an entry of a
32
+ * contract's `testData`; both are contract-local vocabulary, and a corpus
33
+ * signature that carried either would resolve nothing against a second
34
+ * contract. The rejection is structural, so a probe carrying one fails to parse
35
+ * rather than qualifying and then matching nothing.
36
+ */
37
+ export declare const ProbeBindingValue: z.ZodUnion<readonly [z.ZodObject<{
38
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
39
+ }, z.core.$strict>, z.ZodObject<{
40
+ matcher: z.ZodEnum<{
41
+ any: "any";
42
+ "type-violating": "type-violating";
43
+ }>;
44
+ }, z.core.$strict>]>;
45
+ /** the constraint identifier the ledger carries for the check below. */
46
+ export declare const PROBE_BINDING_CHANNEL_NON_EMPTY = "probe-binding-channel-non-empty";
47
+ export declare const ProbeBindingChannel: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
48
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
49
+ }, z.core.$strict>, z.ZodObject<{
50
+ matcher: z.ZodEnum<{
51
+ any: "any";
52
+ "type-violating": "type-violating";
53
+ }>;
54
+ }, z.core.$strict>]>>>;
55
+ /**
56
+ * The four transport channels, spelled exactly as `InputBinding` and
57
+ * `ObservedCallInputs` spell them. The three shapes agree on channel names, on
58
+ * the four-key strict form, and on flatness, so the selector filters recorded
59
+ * call inputs with no shape to bridge.
60
+ */
61
+ export declare const ProbeInputBinding: z.ZodObject<{
62
+ path: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
63
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
64
+ }, z.core.$strict>, z.ZodObject<{
65
+ matcher: z.ZodEnum<{
66
+ any: "any";
67
+ "type-violating": "type-violating";
68
+ }>;
69
+ }, z.core.$strict>]>>>;
70
+ query: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
71
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
72
+ }, z.core.$strict>, z.ZodObject<{
73
+ matcher: z.ZodEnum<{
74
+ any: "any";
75
+ "type-violating": "type-violating";
76
+ }>;
77
+ }, z.core.$strict>]>>>;
78
+ header: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
79
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
80
+ }, z.core.$strict>, z.ZodObject<{
81
+ matcher: z.ZodEnum<{
82
+ any: "any";
83
+ "type-violating": "type-violating";
84
+ }>;
85
+ }, z.core.$strict>]>>>;
86
+ body: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
87
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
88
+ }, z.core.$strict>, z.ZodObject<{
89
+ matcher: z.ZodEnum<{
90
+ any: "any";
91
+ "type-violating": "type-violating";
92
+ }>;
93
+ }, z.core.$strict>]>>>;
94
+ }, z.core.$strict>;
95
+ /**
96
+ * AD-39's selector grammar, duplicated on the corpus side, minus the two
97
+ * members a corpus cannot fill. The operation is the signature's own home
98
+ * operation and is not repeated here; the temporal clause is dropped because no
99
+ * corpus signature needs it. A state-corruption defect that only fires on a
100
+ * second call is already expressible as a predicate over any single
101
+ * observation, and AD-40's mapping is per probe rather than per call sequence.
102
+ * What would reopen the question is pair-defect signatures across the monotonic
103
+ * observation sequence, a future need `preflight/witness-evidence.ts` already
104
+ * records.
105
+ */
106
+ export declare const ProbeStepSelector: z.ZodObject<{
107
+ inputBinding: z.ZodObject<{
108
+ path: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
109
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
110
+ }, z.core.$strict>, z.ZodObject<{
111
+ matcher: z.ZodEnum<{
112
+ any: "any";
113
+ "type-violating": "type-violating";
114
+ }>;
115
+ }, z.core.$strict>]>>>;
116
+ query: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
117
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
118
+ }, z.core.$strict>, z.ZodObject<{
119
+ matcher: z.ZodEnum<{
120
+ any: "any";
121
+ "type-violating": "type-violating";
122
+ }>;
123
+ }, z.core.$strict>]>>>;
124
+ header: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
125
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
126
+ }, z.core.$strict>, z.ZodObject<{
127
+ matcher: z.ZodEnum<{
128
+ any: "any";
129
+ "type-violating": "type-violating";
130
+ }>;
131
+ }, z.core.$strict>]>>>;
132
+ body: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
133
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
134
+ }, z.core.$strict>, z.ZodObject<{
135
+ matcher: z.ZodEnum<{
136
+ any: "any";
137
+ "type-violating": "type-violating";
138
+ }>;
139
+ }, z.core.$strict>]>>>;
140
+ }, z.core.$strict>;
141
+ }, z.core.$strict>;
142
+ /**
143
+ * AD-40's discriminating condition: a selector over observations paired with a
144
+ * predicate over the selected observation's response.
145
+ *
146
+ * The predicate is the shipped `Expression` in AD-4's closed operator
147
+ * vocabulary, never a second relation language. A second vocabulary is a second
148
+ * set of degenerate cases to fix, and AD-4's are already fixed and fixtured.
149
+ * Every pointer in the predicate is rooted at `OBSERVED_STEP_ID`; that rule,
150
+ * the response-channel rule, and AD-4's own legality rules are checked at
151
+ * corpus qualification time rather than here, because each of them is a
152
+ * cross-field or cross-artifact rule the published export cannot carry.
153
+ */
154
+ export declare const DiscriminatingCondition: z.ZodObject<{
155
+ selector: z.ZodObject<{
156
+ inputBinding: z.ZodObject<{
157
+ path: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
158
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
159
+ }, z.core.$strict>, z.ZodObject<{
160
+ matcher: z.ZodEnum<{
161
+ any: "any";
162
+ "type-violating": "type-violating";
163
+ }>;
164
+ }, z.core.$strict>]>>>;
165
+ query: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
166
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
167
+ }, z.core.$strict>, z.ZodObject<{
168
+ matcher: z.ZodEnum<{
169
+ any: "any";
170
+ "type-violating": "type-violating";
171
+ }>;
172
+ }, z.core.$strict>]>>>;
173
+ header: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
174
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
175
+ }, z.core.$strict>, z.ZodObject<{
176
+ matcher: z.ZodEnum<{
177
+ any: "any";
178
+ "type-violating": "type-violating";
179
+ }>;
180
+ }, z.core.$strict>]>>>;
181
+ body: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
182
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
183
+ }, z.core.$strict>, z.ZodObject<{
184
+ matcher: z.ZodEnum<{
185
+ any: "any";
186
+ "type-violating": "type-violating";
187
+ }>;
188
+ }, z.core.$strict>]>>>;
189
+ }, z.core.$strict>;
190
+ }, z.core.$strict>;
191
+ predicate: z.ZodType<Expression, unknown, z.core.$ZodTypeInternals<Expression, unknown>>;
192
+ }, z.core.$strict>;
193
+ /**
194
+ * AD-40's four declarations: the interface kind, the defect's home operation as
195
+ * a method and a path template, the observable channel it manifests in, and the
196
+ * discriminating condition that separates it from correct behaviour.
197
+ *
198
+ * Method and path template rather than an operation identifier, because AD-19
199
+ * declares both per operation and both are contract-independent: an identifier
200
+ * is contract-local and would bind nothing against a second contract.
201
+ * Resolution erases parameter names before comparing, so a signature on
202
+ * `/notes/{id}` binds a contract declaring `/notes/{noteId}`; a post-erasure
203
+ * collision inside one contract has already failed compilation under
204
+ * `duplicate-operation-signature`.
205
+ */
206
+ export declare const DefectSignature: z.ZodObject<{
207
+ interfaceKind: z.ZodEnum<{
208
+ api: "api";
209
+ cli: "cli";
210
+ mcp: "mcp";
211
+ web: "web";
212
+ }>;
213
+ method: z.ZodEnum<{
214
+ DELETE: "DELETE";
215
+ GET: "GET";
216
+ HEAD: "HEAD";
217
+ OPTIONS: "OPTIONS";
218
+ PATCH: "PATCH";
219
+ POST: "POST";
220
+ PUT: "PUT";
221
+ }>;
222
+ pathTemplate: z.ZodString;
223
+ observableChannel: z.ZodEnum<{
224
+ "call-inputs": "call-inputs";
225
+ "exit-code": "exit-code";
226
+ "response-body": "response-body";
227
+ "response-headers": "response-headers";
228
+ "response-status": "response-status";
229
+ stderr: "stderr";
230
+ stdout: "stdout";
231
+ }>;
232
+ condition: z.ZodObject<{
233
+ selector: z.ZodObject<{
234
+ inputBinding: z.ZodObject<{
235
+ path: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
236
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
237
+ }, z.core.$strict>, z.ZodObject<{
238
+ matcher: z.ZodEnum<{
239
+ any: "any";
240
+ "type-violating": "type-violating";
241
+ }>;
242
+ }, z.core.$strict>]>>>;
243
+ query: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
244
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
245
+ }, z.core.$strict>, z.ZodObject<{
246
+ matcher: z.ZodEnum<{
247
+ any: "any";
248
+ "type-violating": "type-violating";
249
+ }>;
250
+ }, z.core.$strict>]>>>;
251
+ header: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
252
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
253
+ }, z.core.$strict>, z.ZodObject<{
254
+ matcher: z.ZodEnum<{
255
+ any: "any";
256
+ "type-violating": "type-violating";
257
+ }>;
258
+ }, z.core.$strict>]>>>;
259
+ body: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
260
+ literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
261
+ }, z.core.$strict>, z.ZodObject<{
262
+ matcher: z.ZodEnum<{
263
+ any: "any";
264
+ "type-violating": "type-violating";
265
+ }>;
266
+ }, z.core.$strict>]>>>;
267
+ }, z.core.$strict>;
268
+ }, z.core.$strict>;
269
+ predicate: z.ZodType<Expression, unknown, z.core.$ZodTypeInternals<Expression, unknown>>;
270
+ }, z.core.$strict>;
271
+ }, z.core.$strict>;
272
+ export type DefectSignature = z.infer<typeof DefectSignature>;
273
+ export type ProbeInputBinding = z.infer<typeof ProbeInputBinding>;
@@ -0,0 +1,127 @@
1
+ /** AD-40's machine-readable defect signature and its probe-side selector. */
2
+ import { z } from 'zod';
3
+ import { Expression } from './expression.js';
4
+ import { HttpMethod, InterfaceKind, PathTemplate } from './interface.js';
5
+ import { LiteralBindingValue, MatcherBindingValue } from './plan.js';
6
+ import { EvidenceChannel } from './pointer.js';
7
+ import { KeyName } from './primitives.js';
8
+ /**
9
+ * The reserved step identifier every pointer in a discriminating condition is
10
+ * rooted at. AD-40 requires the predicate to be rooted at the selected
11
+ * observation rather than at a step identifier, and the shipped `Expression`
12
+ * addresses evidence only through an interaction-rooted pointer, so the
13
+ * signature spends one fixed word instead of minting a fourth pointer grammar:
14
+ *
15
+ * /interactions/observed/response-status
16
+ * /interactions/observed/response-body/error/code
17
+ *
18
+ * A fixed word, so no contract-local choice reaches the corpus, and the gate
19
+ * checks contract-independence instead of asserting it. Evaluation is the
20
+ * shipped path with no adapter: build the resolver map with exactly this one
21
+ * key, and resolve.
22
+ *
23
+ * `observed` is a legal `Identifier` and nothing reserves it, so a contract may
24
+ * declare a step by that name. The design is safe because the resolver map is
25
+ * built fresh with exactly one key and is never merged with a plan's
26
+ * observations. That is a stated invariant of this module;
27
+ * `compile/sensitivity-witness.ts` guards the same collision one level in.
28
+ */
29
+ export const OBSERVED_STEP_ID = 'observed';
30
+ /**
31
+ * The probe-side binding value: `{ literal }` and `{ matcher }` only.
32
+ *
33
+ * Deliberately its own union rather than a reuse of `BindingValue`, which also
34
+ * admits `{ captured }` and `{ principal }`. A captured pointer names an
35
+ * earlier step of a contract's plan, and a principal names an entry of a
36
+ * contract's `testData`; both are contract-local vocabulary, and a corpus
37
+ * signature that carried either would resolve nothing against a second
38
+ * contract. The rejection is structural, so a probe carrying one fails to parse
39
+ * rather than qualifying and then matching nothing.
40
+ */
41
+ export const ProbeBindingValue = z.union([
42
+ LiteralBindingValue,
43
+ MatcherBindingValue,
44
+ ]);
45
+ /** the constraint identifier the ledger carries for the check below. */
46
+ export const PROBE_BINDING_CHANNEL_NON_EMPTY = 'probe-binding-channel-non-empty';
47
+ // Caller-keyed by the author's own parameter names, and `{}` is rejected for
48
+ // the same reason the contract-side channel rejects it: a binding channel has
49
+ // exactly one spelling for "binds nothing", which is `null`.
50
+ //
51
+ // Named, like `InputBindingChannel`, so the constraint ledger has one stable
52
+ // address to inject `minProperties` at. Verified rather than assumed: leaving
53
+ // it inlined at four addresses left the rejection Zod-only, and the
54
+ // published-schema differential caught the disagreement on a synthesised
55
+ // witness carrying `{}` in three of the four channels.
56
+ export const ProbeBindingChannel = z
57
+ .record(KeyName, ProbeBindingValue)
58
+ .refine((entries) => Object.keys(entries).length > 0, {
59
+ error: 'a signature selector channel names at least one parameter; an unbound channel is null',
60
+ })
61
+ .nullable()
62
+ .meta({
63
+ id: 'ProbeInputBindingChannel',
64
+ description: "A parameter-name-to-binding-value map for one transport channel of a defect signature's selector, or `null` for a channel the selector binds nothing in. An empty map is rejected: `null` is the only spelling for unbound. Admits `{ literal }` and `{ matcher }` only; `{ captured }` and `{ principal }` are contract-local vocabulary and a corpus signature cannot carry either.",
65
+ });
66
+ /**
67
+ * The four transport channels, spelled exactly as `InputBinding` and
68
+ * `ObservedCallInputs` spell them. The three shapes agree on channel names, on
69
+ * the four-key strict form, and on flatness, so the selector filters recorded
70
+ * call inputs with no shape to bridge.
71
+ */
72
+ export const ProbeInputBinding = z.strictObject({
73
+ path: ProbeBindingChannel,
74
+ query: ProbeBindingChannel,
75
+ header: ProbeBindingChannel,
76
+ body: ProbeBindingChannel,
77
+ });
78
+ /**
79
+ * AD-39's selector grammar, duplicated on the corpus side, minus the two
80
+ * members a corpus cannot fill. The operation is the signature's own home
81
+ * operation and is not repeated here; the temporal clause is dropped because no
82
+ * corpus signature needs it. A state-corruption defect that only fires on a
83
+ * second call is already expressible as a predicate over any single
84
+ * observation, and AD-40's mapping is per probe rather than per call sequence.
85
+ * What would reopen the question is pair-defect signatures across the monotonic
86
+ * observation sequence, a future need `preflight/witness-evidence.ts` already
87
+ * records.
88
+ */
89
+ export const ProbeStepSelector = z.strictObject({
90
+ inputBinding: ProbeInputBinding,
91
+ });
92
+ /**
93
+ * AD-40's discriminating condition: a selector over observations paired with a
94
+ * predicate over the selected observation's response.
95
+ *
96
+ * The predicate is the shipped `Expression` in AD-4's closed operator
97
+ * vocabulary, never a second relation language. A second vocabulary is a second
98
+ * set of degenerate cases to fix, and AD-4's are already fixed and fixtured.
99
+ * Every pointer in the predicate is rooted at `OBSERVED_STEP_ID`; that rule,
100
+ * the response-channel rule, and AD-4's own legality rules are checked at
101
+ * corpus qualification time rather than here, because each of them is a
102
+ * cross-field or cross-artifact rule the published export cannot carry.
103
+ */
104
+ export const DiscriminatingCondition = z.strictObject({
105
+ selector: ProbeStepSelector,
106
+ predicate: Expression.describe("An AD-4 expression over AD-26 response channels, every pointer rooted at the reserved step identifier `observed`. Legality is the corpus qualification gate's: an unchecked predicate admits `existence` over a literal, which is true of every observation and makes the catch rate 1.00 by construction."),
107
+ });
108
+ /**
109
+ * AD-40's four declarations: the interface kind, the defect's home operation as
110
+ * a method and a path template, the observable channel it manifests in, and the
111
+ * discriminating condition that separates it from correct behaviour.
112
+ *
113
+ * Method and path template rather than an operation identifier, because AD-19
114
+ * declares both per operation and both are contract-independent: an identifier
115
+ * is contract-local and would bind nothing against a second contract.
116
+ * Resolution erases parameter names before comparing, so a signature on
117
+ * `/notes/{id}` binds a contract declaring `/notes/{noteId}`; a post-erasure
118
+ * collision inside one contract has already failed compilation under
119
+ * `duplicate-operation-signature`.
120
+ */
121
+ export const DefectSignature = z.strictObject({
122
+ interfaceKind: InterfaceKind.describe('The interface the seeded defect lives behind. All four kinds parse so `unsupported-interface-kind` stays fireable contract-side, and the qualification gate rejects every kind but `api`: `Operation` carries no interface kind and requires a method and a path template with no per-kind variation, so a `cli` or `mcp` signature would declare a meaningless `POST /path`.'),
123
+ method: HttpMethod,
124
+ pathTemplate: PathTemplate,
125
+ observableChannel: EvidenceChannel.describe('AD-26\'s channel the seeded defect manifests in. The qualification gate reads it: a condition passes only if its pointers name this channel, or name two channels with at least one response-side member. That rule exists to reject a condition collapsing to "the evidence contains the string I sent", which is satisfied by a finding that merely echoes its own input.'),
126
+ condition: DiscriminatingCondition,
127
+ });
@@ -87,6 +87,12 @@ export declare const SiblingGroups: z.ZodObject<{
87
87
  export declare const TestData: z.ZodObject<{
88
88
  setup: z.ZodNullable<z.ZodString>;
89
89
  cleanup: z.ZodNullable<z.ZodString>;
90
+ principals: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodObject<{
91
+ kind: z.ZodString;
92
+ }, z.core.$strict>>>;
93
+ resources: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodObject<{
94
+ kind: z.ZodString;
95
+ }, z.core.$strict>>>;
90
96
  }, z.core.$strict>;
91
97
  export declare const Budgets: z.ZodObject<{
92
98
  maxToolCalls: z.ZodInt;
@@ -329,6 +335,10 @@ export declare const EvalContract: z.ZodObject<{
329
335
  any: "any";
330
336
  "type-violating": "type-violating";
331
337
  }>;
338
+ }, z.core.$strict>, z.ZodObject<{
339
+ captured: z.ZodString;
340
+ }, z.core.$strict>, z.ZodObject<{
341
+ principal: z.ZodString;
332
342
  }, z.core.$strict>]>>>;
333
343
  query: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
334
344
  literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
@@ -337,6 +347,10 @@ export declare const EvalContract: z.ZodObject<{
337
347
  any: "any";
338
348
  "type-violating": "type-violating";
339
349
  }>;
350
+ }, z.core.$strict>, z.ZodObject<{
351
+ captured: z.ZodString;
352
+ }, z.core.$strict>, z.ZodObject<{
353
+ principal: z.ZodString;
340
354
  }, z.core.$strict>]>>>;
341
355
  header: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
342
356
  literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
@@ -345,6 +359,10 @@ export declare const EvalContract: z.ZodObject<{
345
359
  any: "any";
346
360
  "type-violating": "type-violating";
347
361
  }>;
362
+ }, z.core.$strict>, z.ZodObject<{
363
+ captured: z.ZodString;
364
+ }, z.core.$strict>, z.ZodObject<{
365
+ principal: z.ZodString;
348
366
  }, z.core.$strict>]>>>;
349
367
  body: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
350
368
  literal: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
@@ -353,9 +371,18 @@ export declare const EvalContract: z.ZodObject<{
353
371
  any: "any";
354
372
  "type-violating": "type-violating";
355
373
  }>;
374
+ }, z.core.$strict>, z.ZodObject<{
375
+ captured: z.ZodString;
376
+ }, z.core.$strict>, z.ZodObject<{
377
+ principal: z.ZodString;
356
378
  }, z.core.$strict>]>>>;
357
379
  }, z.core.$strict>;
358
380
  after: z.ZodNullable<z.ZodString>;
381
+ cardinality: z.ZodEnum<{
382
+ any: "any";
383
+ "at-most-one": "at-most-one";
384
+ "exactly-one": "exactly-one";
385
+ }>;
359
386
  }, z.core.$strict>>;
360
387
  scopedResources: z.ZodNullable<z.ZodArray<z.ZodObject<{
361
388
  reference: z.ZodString;
@@ -373,6 +400,12 @@ export declare const EvalContract: z.ZodObject<{
373
400
  testData: z.ZodObject<{
374
401
  setup: z.ZodNullable<z.ZodString>;
375
402
  cleanup: z.ZodNullable<z.ZodString>;
403
+ principals: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodObject<{
404
+ kind: z.ZodString;
405
+ }, z.core.$strict>>>;
406
+ resources: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodObject<{
407
+ kind: z.ZodString;
408
+ }, z.core.$strict>>>;
376
409
  }, z.core.$strict>;
377
410
  budgets: z.ZodObject<{
378
411
  maxToolCalls: z.ZodInt;
@@ -82,9 +82,23 @@ export const SiblingGroups = z.strictObject({
82
82
  operations: z.array(z.array(Identifier).min(SIBLING_GROUP_MINIMUM)),
83
83
  parameters: z.array(z.array(KeyName).min(SIBLING_GROUP_MINIMUM)),
84
84
  });
85
+ /**
86
+ * A valueless test-data declaration, keyed by name. `kind` stays opaque for
87
+ * the reason `ScopedResource` above already records: no AD supplies a value
88
+ * space, and inventing one is the unshaped-declaration defect in reverse.
89
+ */
90
+ const TestDataDeclaration = z.strictObject({ kind: z.string().min(1) });
85
91
  export const TestData = z.strictObject({
86
92
  setup: z.string().nullable(),
87
93
  cleanup: z.string().nullable(),
94
+ principals: z
95
+ .record(Identifier, TestDataDeclaration)
96
+ .nullable()
97
+ .describe("Owed item 3: the principals a `{ principal }` input binding may name. Caller-keyed by name, which makes a duplicate declaration unrepresentable, and valueless, since AD-19 forbids a credential value in a declaration and AD-18 keeps the name an opaque label. `null`, `{}`, and a populated map are three distinct answers, on `referenceSets`' own reasoning. A binding naming a key absent here still parses; it fires `undeclared-mandatory-input` at compile time in strict mode, because a cross-subtree constraint reaching from `interactionPlan` into this field cannot survive the export. Required, not optional, which makes this and `resources` below together the eval contract's `schemaVersion` 2 -> 3 BREAKING bump under AD-11, whose rule is that \"adding an optional field is a `schemaVersion` bump recorded in the field's own description; removing or retyping is breaking\". `null` is the legal spelling for a contract declaring none, but `TestData` is a `strictObject` and the key itself must be present, so no version-2 contract parses."),
98
+ resources: z
99
+ .record(Identifier, TestDataDeclaration)
100
+ .nullable()
101
+ .describe("Test-data resources, declared the same way as `principals` above. Any entry fires `scoped-reference-resolves-forbidden` at compile time exactly as a `scopedResources` entry does: a resource the contract points the evaluator at is a scoped reference wherever it is written down (AD-16). Required on the same terms as `principals`, and the other half of the eval contract's `schemaVersion` 2 -> 3 BREAKING bump under AD-11: `null` is the empty spelling and the key is mandatory."),
88
102
  });
89
103
  export const Budgets = z.strictObject({
90
104
  maxToolCalls: z.int().min(0),