eval-quality 0.1.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 (179) hide show
  1. package/README.md +142 -67
  2. package/corpus/dev/README.md +20 -13
  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/application/index.d.ts +2 -0
  28. package/dist/application/index.js +1 -0
  29. package/dist/application/score.d.ts +48 -0
  30. package/dist/application/score.js +186 -0
  31. package/dist/cli/arguments.d.ts +7 -3
  32. package/dist/cli/arguments.js +73 -5
  33. package/dist/cli/exit-codes.d.ts +6 -2
  34. package/dist/cli/exit-codes.js +8 -9
  35. package/dist/cli/main.js +9 -0
  36. package/dist/cli/render.d.ts +3 -6
  37. package/dist/cli/render.js +57 -5
  38. package/dist/cli/run.d.ts +13 -3
  39. package/dist/cli/run.js +136 -16
  40. package/dist/core/canonical/canonicalize.d.ts +12 -0
  41. package/dist/core/canonical/canonicalize.js +18 -4
  42. package/dist/core/compile/bindings.d.ts +89 -0
  43. package/dist/core/compile/bindings.js +334 -0
  44. package/dist/core/compile/compile.d.ts +17 -0
  45. package/dist/core/compile/compile.js +37 -1
  46. package/dist/core/compile/excluded-content.d.ts +11 -0
  47. package/dist/core/compile/excluded-content.js +42 -0
  48. package/dist/core/compile/expression-legality.d.ts +49 -0
  49. package/dist/core/compile/expression-legality.js +158 -38
  50. package/dist/core/compile/forbidden-inputs.d.ts +8 -1
  51. package/dist/core/compile/forbidden-inputs.js +16 -3
  52. package/dist/core/compile/interface-inventory.d.ts +57 -2
  53. package/dist/core/compile/interface-inventory.js +119 -13
  54. package/dist/core/compile/reachability.d.ts +28 -1
  55. package/dist/core/compile/reachability.js +167 -35
  56. package/dist/core/compile/schema-version.d.ts +2 -0
  57. package/dist/core/compile/schema-version.js +25 -0
  58. package/dist/core/compile/sensitivity-witness.d.ts +31 -12
  59. package/dist/core/compile/sensitivity-witness.js +110 -23
  60. package/dist/core/compile/step-reference.d.ts +2 -0
  61. package/dist/core/compile/step-reference.js +49 -0
  62. package/dist/core/coverage/operations.d.ts +62 -0
  63. package/dist/core/coverage/operations.js +57 -0
  64. package/dist/core/coverage/relevance.d.ts +4 -2
  65. package/dist/core/coverage/relevance.js +22 -23
  66. package/dist/core/coverage/satisfaction.d.ts +2 -2
  67. package/dist/core/coverage/satisfaction.js +73 -48
  68. package/dist/core/declared-inputs.d.ts +83 -4
  69. package/dist/core/declared-inputs.js +105 -8
  70. package/dist/core/emit/emit.d.ts +9 -0
  71. package/dist/core/emit/emit.js +214 -0
  72. package/dist/core/emit/private-artifact-digest.d.ts +11 -0
  73. package/dist/core/emit/private-artifact-digest.js +31 -0
  74. package/dist/core/evaluate/evidence-resolution.d.ts +10 -3
  75. package/dist/core/evaluate/evidence-resolution.js +74 -11
  76. package/dist/core/evaluate/operators.d.ts +22 -0
  77. package/dist/core/evaluate/operators.js +17 -1
  78. package/dist/core/evaluate/resolution.d.ts +14 -3
  79. package/dist/core/evaluate/resolution.js +63 -3
  80. package/dist/core/excluded-content.d.ts +65 -0
  81. package/dist/core/excluded-content.js +113 -0
  82. package/dist/core/failure-codes.d.ts +2 -2
  83. package/dist/core/failure-codes.js +7 -2
  84. package/dist/core/ingest/conditions.d.ts +201 -0
  85. package/dist/core/ingest/conditions.js +48 -0
  86. package/dist/core/ingest/index.d.ts +13 -0
  87. package/dist/core/ingest/index.js +11 -0
  88. package/dist/core/ingest/ingest.d.ts +68 -0
  89. package/dist/core/ingest/ingest.js +318 -0
  90. package/dist/core/lineage/stage-table.d.ts +21 -4
  91. package/dist/core/lineage/stage-table.js +35 -3
  92. package/dist/core/preflight/plan.d.ts +7 -5
  93. package/dist/core/preflight/plan.js +75 -32
  94. package/dist/core/preflight/projection.d.ts +6 -3
  95. package/dist/core/preflight/projection.js +22 -2
  96. package/dist/core/preflight/reduce.js +47 -7
  97. package/dist/core/preflight/witness-evidence.d.ts +5 -5
  98. package/dist/core/preflight/witness-evidence.js +73 -20
  99. package/dist/core/schemas/artifact.d.ts +1049 -30
  100. package/dist/core/schemas/constraint-ledger.js +51 -0
  101. package/dist/core/schemas/defect-signature.d.ts +695 -0
  102. package/dist/core/schemas/defect-signature.js +175 -0
  103. package/dist/core/schemas/eval-contract.d.ts +550 -12
  104. package/dist/core/schemas/eval-contract.js +32 -2
  105. package/dist/core/schemas/evidence-artifact.d.ts +109 -19
  106. package/dist/core/schemas/evidence-artifact.js +64 -8
  107. package/dist/core/schemas/interface.d.ts +741 -13
  108. package/dist/core/schemas/interface.js +120 -7
  109. package/dist/core/schemas/isolation-manifest.js +16 -9
  110. package/dist/core/schemas/plan.d.ts +329 -3
  111. package/dist/core/schemas/plan.js +89 -3
  112. package/dist/core/schemas/pointer.d.ts +47 -1
  113. package/dist/core/schemas/pointer.js +89 -8
  114. package/dist/core/schemas/port-messages.d.ts +194 -10
  115. package/dist/core/schemas/port-messages.js +73 -6
  116. package/dist/core/schemas/probe-body.d.ts +18 -0
  117. package/dist/core/schemas/probe-body.js +13 -0
  118. package/dist/core/schemas/probe-qualification.d.ts +168 -0
  119. package/dist/core/schemas/probe-qualification.js +106 -0
  120. package/dist/core/schemas/probe.d.ts +431 -0
  121. package/dist/core/schemas/probe.js +6 -2
  122. package/dist/core/schemas/scoring-policy.d.ts +1 -0
  123. package/dist/core/schemas/scoring-policy.js +6 -1
  124. package/dist/core/schemas/sealed-evaluator-brief.d.ts +1 -0
  125. package/dist/core/schemas/sealed-evaluator-brief.js +4 -1
  126. package/dist/core/schemas/sealed-run-record.d.ts +161 -12
  127. package/dist/core/schemas/sealed-run-record.js +92 -15
  128. package/dist/core/schemas/sensitivity-witness.d.ts +108 -6
  129. package/dist/core/schemas/sensitivity-witness.js +61 -5
  130. package/dist/core/score/binding-order.d.ts +31 -0
  131. package/dist/core/score/binding-order.js +88 -0
  132. package/dist/core/score/bindings.d.ts +93 -0
  133. package/dist/core/score/bindings.js +309 -0
  134. package/dist/core/score/ladder-table.d.ts +23 -0
  135. package/dist/core/score/ladder-table.js +109 -0
  136. package/dist/core/score/ladder.d.ts +229 -0
  137. package/dist/core/score/ladder.js +464 -0
  138. package/dist/core/score/mode-agreement.d.ts +30 -0
  139. package/dist/core/score/mode-agreement.js +16 -0
  140. package/dist/core/score/outcome-table.d.ts +17 -0
  141. package/dist/core/score/outcome-table.js +172 -0
  142. package/dist/core/score/outcome.d.ts +466 -0
  143. package/dist/core/score/outcome.js +562 -0
  144. package/dist/core/score/qualification.d.ts +83 -0
  145. package/dist/core/score/qualification.js +645 -0
  146. package/dist/core/score/quotation.d.ts +56 -0
  147. package/dist/core/score/quotation.js +226 -0
  148. package/dist/core/score/reduce-trials.d.ts +80 -0
  149. package/dist/core/score/reduce-trials.js +90 -0
  150. package/dist/core/score/score.d.ts +72 -0
  151. package/dist/core/score/score.js +607 -0
  152. package/dist/core/score/selection.d.ts +80 -0
  153. package/dist/core/score/selection.js +98 -0
  154. package/dist/core/score/strength.d.ts +58 -0
  155. package/dist/core/score/strength.js +227 -0
  156. package/dist/core/score/witness.d.ts +138 -0
  157. package/dist/core/score/witness.js +320 -0
  158. package/dist/core/seal/derived-reference.d.ts +2 -9
  159. package/dist/core/seal/derived-reference.js +293 -46
  160. package/dist/core/seal/plan-index.d.ts +18 -3
  161. package/dist/core/seal/plan-index.js +44 -8
  162. package/dist/core/seal/seal.js +8 -3
  163. package/dist/core/stage-contracts.d.ts +62 -2
  164. package/dist/index.d.ts +1 -1
  165. package/dist/index.js +1 -1
  166. package/dist/ports/environment-probe-port.d.ts +60 -4
  167. package/dist/testing/index.d.ts +2 -0
  168. package/dist/testing/index.js +1 -0
  169. package/dist/testing/probe-conformance.d.ts +29 -0
  170. package/dist/testing/probe-conformance.js +34 -5
  171. package/package.json +12 -3
  172. package/schemas/eval-contract.schema.json +1787 -797
  173. package/schemas/evidence-artifact.schema.json +126 -9
  174. package/schemas/isolation-manifest.schema.json +17 -10
  175. package/schemas/probe.schema.json +636 -5
  176. package/schemas/rubric.schema.json +1 -1
  177. package/schemas/scoring-policy.schema.json +8 -1
  178. package/schemas/sealed-evaluator-brief.schema.json +11 -1
  179. package/schemas/sealed-run-record.schema.json +314 -40
@@ -5,8 +5,38 @@ import { JsonValue } from './primitives.ts';
5
5
  * AD-23's verbatim quotation, paired with the channel it came from: a
6
6
  * quotation with no channel cannot be audited against its source observation
7
7
  * (ADR-009 Decision 2).
8
+ *
9
+ * Two arms rather than one shape with a nullable identifier and a `.refine()`
10
+ * over the pair. The identifier is meaningful on exactly one channel, and the
11
+ * first spelling of this field said so in prose while admitting every other
12
+ * combination: `channel: "response-body"` with a non-null `artifactId` parsed,
13
+ * and `projectChannel` reads the identifier only on the artifact channel, so
14
+ * the quotation was audited against the response body and a record naming a
15
+ * file it never consulted produced no condition at all. That is a narrower
16
+ * spelling of the wrong-file hole `artifactId` was added to close.
17
+ *
18
+ * A refinement would not have closed it either, for the reason
19
+ * `evidence-artifact.ts` records where it narrows a mode to a literal instead:
20
+ * a refinement never exports, so the published document keeps admitting the
21
+ * disagreement, and AD-13's corpus-mutation generator synthesises witnesses
22
+ * from a branch's own JSON Schema with no knowledge of a Zod-only cross-field
23
+ * rule. Narrowing the schema removes the gap at its source.
24
+ *
25
+ * A plain union rather than a discriminated one, on `DefectSignature`'s own
26
+ * reasoning: the discriminator would be `channel`, and one arm carries seven
27
+ * values for it. The two arms are told apart by the channel they name.
28
+ *
29
+ * The `EvidenceChannel` `$ref` is not carried at this site, since neither arm
30
+ * accepts the whole vocabulary. A non-TypeScript consumer reads a literal on
31
+ * one arm and a seven-member enum on the other, which is the rule itself
32
+ * rather than a reference plus a sentence about it.
8
33
  */
9
- export declare const QuotedEvidence: z.ZodObject<{
34
+ export declare const ArtifactQuotedEvidence: z.ZodObject<{
35
+ quote: z.ZodString;
36
+ channel: z.ZodLiteral<"artifact">;
37
+ artifactId: z.ZodString;
38
+ }, z.core.$strict>;
39
+ export declare const ChannelQuotedEvidence: z.ZodObject<{
10
40
  quote: z.ZodString;
11
41
  channel: z.ZodEnum<{
12
42
  "call-inputs": "call-inputs";
@@ -17,7 +47,25 @@ export declare const QuotedEvidence: z.ZodObject<{
17
47
  stderr: "stderr";
18
48
  stdout: "stdout";
19
49
  }>;
50
+ artifactId: z.ZodNull;
20
51
  }, z.core.$strict>;
52
+ export declare const QuotedEvidence: z.ZodUnion<readonly [z.ZodObject<{
53
+ quote: z.ZodString;
54
+ channel: z.ZodLiteral<"artifact">;
55
+ artifactId: z.ZodString;
56
+ }, z.core.$strict>, z.ZodObject<{
57
+ quote: z.ZodString;
58
+ channel: z.ZodEnum<{
59
+ "call-inputs": "call-inputs";
60
+ "exit-code": "exit-code";
61
+ "response-body": "response-body";
62
+ "response-headers": "response-headers";
63
+ "response-status": "response-status";
64
+ stderr: "stderr";
65
+ stdout: "stdout";
66
+ }>;
67
+ artifactId: z.ZodNull;
68
+ }, z.core.$strict>]>;
21
69
  /**
22
70
  * `defect` findings additionally require observation identifiers and quoted
23
71
  * evidence (AD-23). A nullable field can't express "required on this branch
@@ -49,7 +97,11 @@ export declare const Finding: z.ZodDiscriminatedUnion<[z.ZodObject<{
49
97
  }, z.core.$strict>], "storage">>;
50
98
  findingType: z.ZodLiteral<"defect">;
51
99
  observationIds: z.ZodArray<z.ZodString>;
52
- quotedEvidence: z.ZodArray<z.ZodObject<{
100
+ quotedEvidence: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
101
+ quote: z.ZodString;
102
+ channel: z.ZodLiteral<"artifact">;
103
+ artifactId: z.ZodString;
104
+ }, z.core.$strict>, z.ZodObject<{
53
105
  quote: z.ZodString;
54
106
  channel: z.ZodEnum<{
55
107
  "call-inputs": "call-inputs";
@@ -60,7 +112,8 @@ export declare const Finding: z.ZodDiscriminatedUnion<[z.ZodObject<{
60
112
  stderr: "stderr";
61
113
  stdout: "stdout";
62
114
  }>;
63
- }, z.core.$strict>>;
115
+ artifactId: z.ZodNull;
116
+ }, z.core.$strict>]>>;
64
117
  }, z.core.$strict>, z.ZodObject<{
65
118
  findingId: z.ZodString;
66
119
  oracleId: z.ZodNullable<z.ZodString>;
@@ -132,6 +185,7 @@ export declare const OracleDisposition: z.ZodObject<{
132
185
  observationIds: z.ZodArray<z.ZodString>;
133
186
  note: z.ZodNullable<z.ZodString>;
134
187
  }, z.core.$strict>;
188
+ export type OracleDisposition = z.infer<typeof OracleDisposition>;
135
189
  /**
136
190
  * A flat map would break pointer addressing: AD-26 keys `call-inputs` by
137
191
  * transport channel, so a pointer like
@@ -146,34 +200,71 @@ export declare const ObservedCallInputs: z.ZodObject<{
146
200
  query: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
147
201
  header: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
148
202
  body: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
203
+ argument: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
204
+ option: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
205
+ environment: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
206
+ stdin: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
149
207
  }, z.core.$strict>;
208
+ /** the constraint identifier the ledger carries for the check below. */
209
+ export declare const OBSERVATION_SEQUENCE_UNIQUE = "observation-sequence-unique";
150
210
  /**
151
211
  * One ingested observation, carrying AD-26's closed channel set so every
152
212
  * pointer in the addressing grammar has something to resolve against.
153
213
  *
154
- * Observation ordering is deliberately absent (Owed item 2): ADR-006 forbids
155
- * using array position as ordering, and the fix, a monotonic sequence, arrives
156
- * as an additive `schemaVersion` bump under AD-11.
214
+ * `sequence` closes owed item 2: ADR-006 forbids using array position as
215
+ * ordering. A required, per-record-unique `sequence` is the total order a
216
+ * selector reads.
157
217
  */
158
218
  export declare const Observation: z.ZodObject<{
159
219
  observationId: z.ZodString;
220
+ sequence: z.ZodInt;
160
221
  operationId: z.ZodString;
161
222
  provenance: z.ZodEnum<{
162
223
  baseline: "baseline";
163
224
  "evaluator-chosen": "evaluator-chosen";
164
225
  }>;
226
+ principal: z.ZodNullable<z.ZodString>;
165
227
  callInputs: z.ZodObject<{
166
228
  path: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
167
229
  query: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
168
230
  header: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
169
231
  body: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
232
+ argument: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
233
+ option: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
234
+ environment: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
235
+ stdin: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
170
236
  }, z.core.$strict>;
171
237
  responseBody: z.ZodNullable<z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>>;
172
238
  responseHeaders: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
173
239
  responseStatus: z.ZodNullable<z.ZodInt>;
174
- stdout: z.ZodNullable<z.ZodString>;
175
- stderr: z.ZodNullable<z.ZodString>;
240
+ stdout: z.ZodDiscriminatedUnion<[z.ZodObject<{
241
+ kind: z.ZodLiteral<"json">;
242
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
243
+ }, z.core.$strict>, z.ZodObject<{
244
+ kind: z.ZodLiteral<"text">;
245
+ value: z.ZodString;
246
+ }, z.core.$strict>, z.ZodObject<{
247
+ kind: z.ZodLiteral<"absent">;
248
+ }, z.core.$strict>], "kind">;
249
+ stderr: z.ZodDiscriminatedUnion<[z.ZodObject<{
250
+ kind: z.ZodLiteral<"json">;
251
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
252
+ }, z.core.$strict>, z.ZodObject<{
253
+ kind: z.ZodLiteral<"text">;
254
+ value: z.ZodString;
255
+ }, z.core.$strict>, z.ZodObject<{
256
+ kind: z.ZodLiteral<"absent">;
257
+ }, z.core.$strict>], "kind">;
176
258
  exitCode: z.ZodNullable<z.ZodInt>;
259
+ artifacts: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
260
+ kind: z.ZodLiteral<"json">;
261
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
262
+ }, z.core.$strict>, z.ZodObject<{
263
+ kind: z.ZodLiteral<"text">;
264
+ value: z.ZodString;
265
+ }, z.core.$strict>, z.ZodObject<{
266
+ kind: z.ZodLiteral<"absent">;
267
+ }, z.core.$strict>], "kind">>;
177
268
  }, z.core.$strict>;
178
269
  export type ObservedCallInputs = z.infer<typeof ObservedCallInputs>;
179
270
  export type Observation = z.infer<typeof Observation>;
@@ -205,12 +296,34 @@ export declare const EvidenceDisclosure: z.ZodObject<{
205
296
  truncationBound: z.ZodNullable<z.ZodInt>;
206
297
  reportedIncomplete: z.ZodBoolean;
207
298
  }, z.core.$strict>;
299
+ /** exported so the ladder names this shape without importing Zod. */
300
+ export type EvidenceDisclosure = z.infer<typeof EvidenceDisclosure>;
301
+ /**
302
+ * AD-21's two modes, closed. In `production` the subject is the system under
303
+ * test; in `contract-scoring` the subject is the contract, the probe is
304
+ * knowingly defective, and a `caught` outcome is the contract succeeding.
305
+ *
306
+ * Declared on the record rather than on the evidence artifact because this is
307
+ * where mode is now fixed: AD-21 requires mode "fixed before ingest", and an
308
+ * evidence artifact is `emit`'s output, four stages past the only place a
309
+ * caller can supply one.
310
+ */
311
+ export declare const RUN_MODES: readonly ['production', 'contract-scoring'];
312
+ export type RunModeValue = (typeof RUN_MODES)[number];
313
+ export declare const RunMode: z.ZodEnum<{
314
+ "contract-scoring": "contract-scoring";
315
+ production: "production";
316
+ }>;
208
317
  export declare const SealedRunRecord: z.ZodObject<{
209
318
  schemaVersion: z.ZodInt;
210
319
  parentDigest: z.ZodNullable<z.ZodString>;
211
320
  revisionCount: z.ZodInt;
212
321
  runId: z.ZodString;
213
322
  conditionArm: z.ZodString;
323
+ mode: z.ZodEnum<{
324
+ "contract-scoring": "contract-scoring";
325
+ production: "production";
326
+ }>;
214
327
  trialIndex: z.ZodInt;
215
328
  contractDigest: z.ZodString;
216
329
  sealedBriefDigest: z.ZodString;
@@ -255,7 +368,11 @@ export declare const SealedRunRecord: z.ZodObject<{
255
368
  }, z.core.$strict>], "storage">>;
256
369
  findingType: z.ZodLiteral<"defect">;
257
370
  observationIds: z.ZodArray<z.ZodString>;
258
- quotedEvidence: z.ZodArray<z.ZodObject<{
371
+ quotedEvidence: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
372
+ quote: z.ZodString;
373
+ channel: z.ZodLiteral<"artifact">;
374
+ artifactId: z.ZodString;
375
+ }, z.core.$strict>, z.ZodObject<{
259
376
  quote: z.ZodString;
260
377
  channel: z.ZodEnum<{
261
378
  "call-inputs": "call-inputs";
@@ -266,7 +383,8 @@ export declare const SealedRunRecord: z.ZodObject<{
266
383
  stderr: "stderr";
267
384
  stdout: "stdout";
268
385
  }>;
269
- }, z.core.$strict>>;
386
+ artifactId: z.ZodNull;
387
+ }, z.core.$strict>]>>;
270
388
  }, z.core.$strict>, z.ZodObject<{
271
389
  findingId: z.ZodString;
272
390
  oracleId: z.ZodNullable<z.ZodString>;
@@ -320,23 +438,54 @@ export declare const SealedRunRecord: z.ZodObject<{
320
438
  }, z.core.$strict>], "findingType">>;
321
439
  observations: z.ZodArray<z.ZodObject<{
322
440
  observationId: z.ZodString;
441
+ sequence: z.ZodInt;
323
442
  operationId: z.ZodString;
324
443
  provenance: z.ZodEnum<{
325
444
  baseline: "baseline";
326
445
  "evaluator-chosen": "evaluator-chosen";
327
446
  }>;
447
+ principal: z.ZodNullable<z.ZodString>;
328
448
  callInputs: z.ZodObject<{
329
449
  path: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
330
450
  query: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
331
451
  header: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
332
452
  body: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
453
+ argument: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
454
+ option: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
455
+ environment: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
456
+ stdin: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
333
457
  }, z.core.$strict>;
334
458
  responseBody: z.ZodNullable<z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>>;
335
459
  responseHeaders: z.ZodNullable<z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>>;
336
460
  responseStatus: z.ZodNullable<z.ZodInt>;
337
- stdout: z.ZodNullable<z.ZodString>;
338
- stderr: z.ZodNullable<z.ZodString>;
461
+ stdout: z.ZodDiscriminatedUnion<[z.ZodObject<{
462
+ kind: z.ZodLiteral<"json">;
463
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
464
+ }, z.core.$strict>, z.ZodObject<{
465
+ kind: z.ZodLiteral<"text">;
466
+ value: z.ZodString;
467
+ }, z.core.$strict>, z.ZodObject<{
468
+ kind: z.ZodLiteral<"absent">;
469
+ }, z.core.$strict>], "kind">;
470
+ stderr: z.ZodDiscriminatedUnion<[z.ZodObject<{
471
+ kind: z.ZodLiteral<"json">;
472
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
473
+ }, z.core.$strict>, z.ZodObject<{
474
+ kind: z.ZodLiteral<"text">;
475
+ value: z.ZodString;
476
+ }, z.core.$strict>, z.ZodObject<{
477
+ kind: z.ZodLiteral<"absent">;
478
+ }, z.core.$strict>], "kind">;
339
479
  exitCode: z.ZodNullable<z.ZodInt>;
480
+ artifacts: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
481
+ kind: z.ZodLiteral<"json">;
482
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
483
+ }, z.core.$strict>, z.ZodObject<{
484
+ kind: z.ZodLiteral<"text">;
485
+ value: z.ZodString;
486
+ }, z.core.$strict>, z.ZodObject<{
487
+ kind: z.ZodLiteral<"absent">;
488
+ }, z.core.$strict>], "kind">>;
340
489
  }, z.core.$strict>>;
341
490
  judgeResults: z.ZodArray<z.ZodObject<{
342
491
  rubricId: z.ZodString;
@@ -3,21 +3,58 @@ import { z } from 'zod';
3
3
  import { ArtifactReference } from './artifact-reference.js';
4
4
  import { Severity } from './eval-contract.js';
5
5
  import { lineageFields } from './lineage.js';
6
- import { EvidenceChannel } from './pointer.js';
6
+ import { IDENTIFIER_ROOTED_CHANNEL, NON_IDENTIFIER_ROOTED_CHANNELS, } from './pointer.js';
7
7
  import { BehaviorId, Digest, FindingId, Identifier, JsonObjectValue, JsonValue, OracleId, ProbeId, RubricCriterionId, RubricId, UnsignedDecimalString, } from './primitives.js';
8
+ import { ProbeObservedBody } from './probe-body.js';
8
9
  import { EvaluatorRecommendation } from './verdict.js';
10
+ const QUOTE_DESCRIPTION = "The evaluator's verbatim quotation, per AD-23. Non-empty: an empty quotation quotes nothing, no AD-5 code names the condition, and under the admit-rule's second clause the schema is therefore the enforcement point. That this text appears in at least one of the finding's cited observations is NOT checked here; it is an AD-32 declared-versus-observed inconsistency that invalidates at ingest, and ADR-009 Decision 2 settles the precedence: \"cited identifiers govern the witness match; quotation audits it.\"";
11
+ const quote = z.string().min(1).describe(QUOTE_DESCRIPTION);
9
12
  /**
10
13
  * AD-23's verbatim quotation, paired with the channel it came from: a
11
14
  * quotation with no channel cannot be audited against its source observation
12
15
  * (ADR-009 Decision 2).
16
+ *
17
+ * Two arms rather than one shape with a nullable identifier and a `.refine()`
18
+ * over the pair. The identifier is meaningful on exactly one channel, and the
19
+ * first spelling of this field said so in prose while admitting every other
20
+ * combination: `channel: "response-body"` with a non-null `artifactId` parsed,
21
+ * and `projectChannel` reads the identifier only on the artifact channel, so
22
+ * the quotation was audited against the response body and a record naming a
23
+ * file it never consulted produced no condition at all. That is a narrower
24
+ * spelling of the wrong-file hole `artifactId` was added to close.
25
+ *
26
+ * A refinement would not have closed it either, for the reason
27
+ * `evidence-artifact.ts` records where it narrows a mode to a literal instead:
28
+ * a refinement never exports, so the published document keeps admitting the
29
+ * disagreement, and AD-13's corpus-mutation generator synthesises witnesses
30
+ * from a branch's own JSON Schema with no knowledge of a Zod-only cross-field
31
+ * rule. Narrowing the schema removes the gap at its source.
32
+ *
33
+ * A plain union rather than a discriminated one, on `DefectSignature`'s own
34
+ * reasoning: the discriminator would be `channel`, and one arm carries seven
35
+ * values for it. The two arms are told apart by the channel they name.
36
+ *
37
+ * The `EvidenceChannel` `$ref` is not carried at this site, since neither arm
38
+ * accepts the whole vocabulary. A non-TypeScript consumer reads a literal on
39
+ * one arm and a seven-member enum on the other, which is the rule itself
40
+ * rather than a reference plus a sentence about it.
13
41
  */
14
- export const QuotedEvidence = z.strictObject({
15
- quote: z
16
- .string()
17
- .min(1)
18
- .describe("The evaluator's verbatim quotation, per AD-23. Non-empty: an empty quotation quotes nothing, no AD-5 code names the condition, and under the admit-rule's second clause the schema is therefore the enforcement point. That this text appears in at least one of the finding's cited observations is NOT checked here; it is an AD-32 declared-versus-observed inconsistency that invalidates at ingest, and ADR-009 Decision 2 settles the precedence: \"cited identifiers govern the witness match; quotation audits it.\""),
19
- channel: EvidenceChannel,
42
+ export const ArtifactQuotedEvidence = z.strictObject({
43
+ quote,
44
+ channel: z.literal(IDENTIFIER_ROOTED_CHANNEL),
45
+ artifactId: Identifier.describe("Which written file the quotation came from. A channel alone does not identify one: an operation may write several, and an audit that searched all of them at once accepted a quotation lifted from a file the finding never cited, which is the opposite of what AD-23's verbatim requirement is for."),
20
46
  });
47
+ export const ChannelQuotedEvidence = z.strictObject({
48
+ quote,
49
+ channel: z.enum(NON_IDENTIFIER_ROOTED_CHANNELS),
50
+ artifactId: z
51
+ .null()
52
+ .describe('Null on every channel but `artifact`, and required rather than optional so a record cannot omit the question. Only a written file needs naming; every other channel is one thing per observation.'),
53
+ });
54
+ export const QuotedEvidence = z.union([
55
+ ArtifactQuotedEvidence,
56
+ ChannelQuotedEvidence,
57
+ ]);
21
58
  // Spread into each finding branch rather than shared as a base object: a
22
59
  // spread adds no `$defs` entry, so each branch exports as a complete shape a
23
60
  // non-TypeScript consumer can read without following a reference (AD-13).
@@ -108,21 +145,32 @@ export const ObservedCallInputs = z.strictObject({
108
145
  query: JsonObjectValue.nullable(),
109
146
  header: JsonObjectValue.nullable(),
110
147
  body: JsonObjectValue.nullable(),
148
+ argument: JsonObjectValue.nullable(),
149
+ option: JsonObjectValue.nullable(),
150
+ environment: JsonObjectValue.nullable(),
151
+ stdin: JsonObjectValue.nullable(),
111
152
  });
153
+ /** the constraint identifier the ledger carries for the check below. */
154
+ export const OBSERVATION_SEQUENCE_UNIQUE = 'observation-sequence-unique';
112
155
  /**
113
156
  * One ingested observation, carrying AD-26's closed channel set so every
114
157
  * pointer in the addressing grammar has something to resolve against.
115
158
  *
116
- * Observation ordering is deliberately absent (Owed item 2): ADR-006 forbids
117
- * using array position as ordering, and the fix, a monotonic sequence, arrives
118
- * as an additive `schemaVersion` bump under AD-11.
159
+ * `sequence` closes owed item 2: ADR-006 forbids using array position as
160
+ * ordering. A required, per-record-unique `sequence` is the total order a
161
+ * selector reads.
119
162
  */
120
163
  export const Observation = z.strictObject({
121
164
  observationId: Identifier,
165
+ sequence: z
166
+ .int()
167
+ .positive()
168
+ .describe('The total order ADR-006 forbids reading off array position (owed item 2). A positive integer, unique across every observation in the same record: uniqueness is what a sorted-by-`sequence` read needs to be strictly increasing, so no separate monotonicity check is required. Neither starting at 1 nor contiguous is required across a record: only positivity and per-record uniqueness are enforced, so a record whose sequences are e.g. [5, 12, 40] is equally valid. Required rather than optional, which makes this a BREAKING `schemaVersion` bump under AD-11: adding an optional field is additive, and this field is not optional. A record with an absent or duplicated `sequence` fails to parse.'),
122
169
  operationId: Identifier.describe('The operation this observation exercised. `Operation.operationId` is scoped to a `PermittedInterface`, so two interfaces may declare the same one; that collision is a cross-artifact rule with no AD-5 code, since `duplicate-operation-signature` covers method plus path template only, and it is left to ingest.'),
123
170
  provenance: z
124
171
  .enum(['baseline', 'evaluator-chosen'])
125
172
  .describe("AD-23: `baseline` for a pre-canned or deterministic test, `evaluator-chosen` for an action the evaluator selected. The distinction is the one the product's central finding rests on: what a sealed evaluator detects beyond the pre-canned baseline. It lives on the observation, never on the finding."),
173
+ principal: Identifier.nullable().describe("The declared principal the harness acted as, or `null` where the run named none. Owed item 3's other half: a `{ principal }` input binding is presence-only by construction, since the contract declares a name and the harness provisions the value, so without this field two steps of one operation binding `owner` and `other-user` both match every observation and both resolve `several`. That is exactly the act-as-A-read-as-B shape the two critical-severity cross-user behaviours need, and it was unscoreable while the record said nothing about which account was used. An opaque label carrying no account identifier or credential, on `testData.principals`' own AD-18 terms."),
126
174
  callInputs: ObservedCallInputs,
127
175
  responseBody: JsonValue.nullable().describe('AD-26\'s `response-body` channel. The null branch is redundant against the value container, which already admits `null`; it is kept so all ten observation fields read the same way, and it means "no body observed" and "a body that was JSON null" are indistinguishable here, which is an accepted cost of one uniform spelling.'),
128
176
  responseHeaders: JsonObjectValue.nullable().describe('A name-to-value map, not the open value container. AD-26 gives `response-headers` a tail, so a pointer resolves INTO this channel; a scalar here would leave `/interactions/x/response-headers/Content-Type` addressing nothing. That is the difference from `responseBody`, where a scalar or an array is a legitimate body and the open container is correct.'),
@@ -131,12 +179,15 @@ export const Observation = z.strictObject({
131
179
  .min(0)
132
180
  .nullable()
133
181
  .describe('Deliberately not bounded to a protocol range. A negative status is meaningless and excluded, but the upper end is left open: AD-19 declares four interface kinds and v0 rejects three of them at compile time under `unsupported-interface-kind`, so bounding this to HTTP would encode a protocol assumption the artifact outlives. `null` where the channel does not apply.'),
134
- stdout: z.string().nullable(),
135
- stderr: z.string().nullable(),
182
+ stdout: ProbeObservedBody.describe('AD-26\'s `stdout` channel, tagged rather than a bare string. An operation may nominate standard output as the channel its response descriptor describes, in which case a pointer descends into it, and an untagged string could not tell output that was JSON from output that was only ever text. `{ "kind": "absent" }` is the channel a run did not observe.'),
183
+ stderr: ProbeObservedBody.describe("AD-26's `stderr` channel, tagged on the same terms as `stdout`."),
136
184
  exitCode: z
137
185
  .int()
138
186
  .nullable()
139
187
  .describe('Signed on purpose, unlike `responseStatus`: a process terminated by a signal is conventionally reported as a negative code, and this field records what was observed rather than what is tidy.'),
188
+ artifacts: z
189
+ .record(Identifier, ProbeObservedBody)
190
+ .describe("AD-26's `artifact` channel, keyed by the identifier the operation declares it writes, which is the segment an artifact pointer carries before its tail. Caller-keyed and expected to be partial: a run that wrote no files carries `{}`. Tagged on the same terms as `stdout`, since a written report may be JSON, may be prose, and may not have been written at all."),
140
191
  });
141
192
  /**
142
193
  * AD-17: judge results arrive inside the sealed run record and the package
@@ -148,7 +199,7 @@ export const JudgeResult = z.strictObject({
148
199
  score: z
149
200
  .int()
150
201
  .nullable()
151
- .describe("An integer, because AD-22 puts the scale on the rubric's own anchored levels and `ScaleLevel.level` is already `z.int()`; no second scale is minted here. `null` is the shape AD-6's `judge-error` fires on, so it must parse. That the criterion is one the cited rubric declares, and that a conforming record shows one judge call scoring all named criteria, are AD-17 cross-artifact rules a schema over one artifact cannot see."),
202
+ .describe("An integer, because AD-22 puts the scale on the rubric's own anchored levels and `ScaleLevel.level` is already `z.int()`; no second scale is minted here. `null` is the shape AD-6's `judge-error` fires on, so it must parse. Two AD-17 rules sit over this field and only one of them is decidable from a record. That a criterion is scored at most once IS: `core/ingest` reports a repeated `rubricId`/`criterionId` pair as a `duplicate-record-identifier` condition, since a criterion scored twice is not one judge call's product whatever else the record says. That a scored criterion is one the cited rubric DECLARES is not, and never will be from inside this package: the rubric is not among ingest's declared inputs, no stage row names it, and a schema over one artifact has no second operand. That half is the caller's, on the same terms AD-12 states for the remediation cap, and it is a stated boundary rather than an unimplemented rule."),
152
203
  note: z.string().nullable(),
153
204
  });
154
205
  /** the prior art's five members, with money as a string per AD-36. */
@@ -178,6 +229,18 @@ export const EvidenceDisclosure = z.strictObject({
178
229
  .boolean()
179
230
  .describe('AD-17: "a case that cannot be bounded without discarding disconfirming material is reported incomplete". This is the operand AD-21\'s incomplete condition reads. The remaining two conditions read no field here: unavailable is an `ArtifactReference` that does not resolve through the corpus port, and internally inconsistent is AD-32\'s cross-artifact agreement check. AD-17\'s "must retain evidence contradicting the leading verdict" is decidable by none of them and is recorded as unenforced in v0.'),
180
231
  });
232
+ /**
233
+ * AD-21's two modes, closed. In `production` the subject is the system under
234
+ * test; in `contract-scoring` the subject is the contract, the probe is
235
+ * knowingly defective, and a `caught` outcome is the contract succeeding.
236
+ *
237
+ * Declared on the record rather than on the evidence artifact because this is
238
+ * where mode is now fixed: AD-21 requires mode "fixed before ingest", and an
239
+ * evidence artifact is `emit`'s output, four stages past the only place a
240
+ * caller can supply one.
241
+ */
242
+ export const RUN_MODES = ['production', 'contract-scoring'];
243
+ export const RunMode = z.enum(RUN_MODES);
181
244
  export const SealedRunRecord = z
182
245
  .strictObject({
183
246
  ...lineageFields,
@@ -189,6 +252,7 @@ export const SealedRunRecord = z
189
252
  .string()
190
253
  .min(1)
191
254
  .describe("An opaque caller label with no product semantics, per AD-24. The prior art's five-member enum does not survive, and its own extension history is the reason: an enum a local amendment had to widen once for `self-review` will be widened again."),
255
+ mode: RunMode.describe('AD-21\'s run mode, supplied by the caller on the record and never derived, recomputed, or defaulted afterwards. AD-21 requires mode to be "fixed before ingest", and owed item 4 records what its absence costs: the same sealed run could be relabelled after ingest and scored under the same scoring version. Required rather than optional, which makes this a BREAKING `schemaVersion` 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". A version-1 record carries no mode, and no default may repair one into a version-2 record, because a defaulted mode is the relabelling this field exists to stop. A record presenting no mode fails to parse, which AD-28 makes a `schema-parse-failure` fault rather than an AD-21 verdict or an AD-5 code, the same routing `evaluatorRecommendation` already records for an unrecognised value. This field is where mode is read from; the evidence artifact restates it and is never the source.'),
192
256
  trialIndex: z
193
257
  .int()
194
258
  .min(1)
@@ -199,7 +263,20 @@ export const SealedRunRecord = z
199
263
  evaluatorRecommendation: EvaluatorRecommendation,
200
264
  oracleDispositions: z.array(OracleDisposition),
201
265
  findings: z.array(Finding),
202
- observations: z.array(Observation),
266
+ observations: z
267
+ .array(Observation)
268
+ .refine((observations) => {
269
+ const seen = new Set();
270
+ for (const observation of observations) {
271
+ if (seen.has(observation.sequence))
272
+ return false;
273
+ seen.add(observation.sequence);
274
+ }
275
+ return true;
276
+ }, {
277
+ error: "every observation's `sequence` is unique within the record (ADR-006, owed item 2); a duplicate leaves the total order the fix exists to supply ambiguous",
278
+ })
279
+ .describe('Per-observation `sequence` uniqueness is enforced here. The published JSON Schema dialect has no keyword for uniqueness of a nested field across array items, so this constraint is Zod-only: a non-Zod consumer must reimplement it, exactly as with any other cross-item invariant this dialect cannot state.'),
203
280
  judgeResults: z
204
281
  .array(JudgeResult)
205
282
  .describe('Empty is legal: a contract with no rubric produces no judge call.'),
@@ -211,5 +288,5 @@ export const SealedRunRecord = z
211
288
  })
212
289
  .meta({
213
290
  id: 'SealedRunRecord',
214
- description: "One sealed evaluator trial, as the caller presents it. Succeeds the prior-art `h0-run-result` schema per AD-24, keeping its run identifier, condition arm, findings, action-log reference, resource use, invalidation reason, evaluator recommendation as a closed enum, and per-finding confidence on a declared scale. Divergences: `condition` is demoted to the opaque `conditionArm`, `verdict` becomes `evaluatorRecommendation` without `NOT_APPLICABLE`, money is a decimal string, and `taskId`, `note`, and per-finding `actionIds` do not survive: the contract is pinned by `contractDigest`, an unstructured orchestrator annotation is the free-prose channel the Conventions close everywhere else, and two citation vocabularies on one finding is the ambiguity ADR-009 removed. Two constructions are deliberately absent and each is owed to an open item: the run MODE, which AD-21 requires to be fixed before ingest and to enter AD-11's identity inputs rather than appearing first in the evidence artifact (Owed item 4), and observation ORDERING, which ADR-006 forbids reading off array position (Owed item 2). Both arrive as additive `schemaVersion` bumps under AD-11.",
291
+ description: "One sealed evaluator trial, as the caller presents it. Succeeds the prior-art `h0-run-result` schema per AD-24, keeping its run identifier, condition arm, findings, action-log reference, resource use, invalidation reason, evaluator recommendation as a closed enum, and per-finding confidence on a declared scale. Divergences: `condition` is demoted to the opaque `conditionArm`, `verdict` becomes `evaluatorRecommendation` without `NOT_APPLICABLE`, money is a decimal string, and `taskId`, `note`, and per-finding `actionIds` do not survive: the contract is pinned by `contractDigest`, an unstructured orchestrator annotation is the free-prose channel the Conventions close everywhere else, and two citation vocabularies on one finding is the ambiguity ADR-009 removed. The run MODE landed here as a required field under a BREAKING `schemaVersion` bump, which is where AD-21's \"fixed before ingest\" puts it; owed item 4 is now closed: mode enters AD-11's identity inputs as `ScoringVersionInputs`'s sixth field, and `core/score/ladder.ts` carries `ProductionAssessment`/`ContractAssessment` as the two assessment input types with their own total ladders. Observation ORDERING landed here too, under its own BREAKING `schemaVersion` bump: `sequence` is required and unique per record, closing owed item 2's ADR-006 gap, since array position was never a legal ordering. Version 4 opened the record to a system under test that runs behind a command: `callInputs` carries the four command channels beside the four transport ones, `stdout` and `stderr` are tagged rather than bare strings so a nominated output channel can be descended into, and `artifacts` records the files the run wrote, keyed by the identifier the operation declares.",
215
292
  });