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
@@ -37,7 +37,7 @@
37
37
  "scoringVersion": {
38
38
  "type": "string",
39
39
  "pattern": "^sha256:[0-9a-f]{64}$",
40
- "description": "AD-11: computed by the scorer over the five named inputs below and never caller-supplied."
40
+ "description": "AD-11: computed by the scorer over the six named inputs below and never caller-supplied."
41
41
  },
42
42
  "scoringVersionInputs": {
43
43
  "type": "object",
@@ -66,6 +66,11 @@
66
66
  "type": "string",
67
67
  "pattern": "^sha256:[0-9a-f]{64}$",
68
68
  "description": "AD-27 digest: \"sha256:\" plus 64 lowercase hexadecimal characters."
69
+ },
70
+ "mode": {
71
+ "type": "string",
72
+ "const": "production",
73
+ "description": "Owed item 4's identity clause: mode enters AD-11's scoring version, superseding AD-11's five-field sentence. Read from the sealed run record, never re-derived, so two runs scored under one mode never collide with a version computed for the other. Required, not optional, which makes this the evidence artifact's `schemaVersion` 1 -> 2 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\". A version-1 artifact carries five scoring-version inputs where this one carries six, so it does not parse, and no version computed before the bump compares with one computed after it."
69
74
  }
70
75
  },
71
76
  "required": [
@@ -73,7 +78,8 @@
73
78
  "corpusDigest",
74
79
  "fixtureDigest",
75
80
  "evaluatorConfigurationDigest",
76
- "scoringPolicyDigest"
81
+ "scoringPolicyDigest",
82
+ "mode"
77
83
  ],
78
84
  "additionalProperties": false
79
85
  },
@@ -113,10 +119,11 @@
113
119
  "corpusDigest",
114
120
  "fixtureDigest",
115
121
  "evaluatorConfigurationDigest",
116
- "scoringPolicyDigest"
122
+ "scoringPolicyDigest",
123
+ "mode"
117
124
  ]
118
125
  },
119
- "description": "Which of the five scoring-version inputs were caller-attested rather than computed by this package. An enum over the five key names rather than free strings, because AD-32 requires the artifact to state *which* inputs were attested and an unconstrained string cannot be checked against anything. AD-11 names three of the five as caller-attested; the enum admits any subset so a stricter or looser integration stays representable."
126
+ "description": "Which of the six scoring-version inputs were caller-attested rather than computed by this package. An enum over the six key names rather than free strings, because AD-32 requires the artifact to state *which* inputs were attested and an unconstrained string cannot be checked against anything. AD-11 names three of the six as caller-attested; the enum admits any subset so a stricter or looser integration stays representable. `mode` is the one member that is not a choice: `ScoringVersionInputs.mode` is read from the sealed run record and never re-derived, so a list omitting it is a misdeclaration rather than a stricter integration. The schema admits that shape and the constraint ledger records why; `core/emit` always names it."
120
127
  },
121
128
  "trials": {
122
129
  "type": "object",
@@ -610,7 +617,7 @@
610
617
  "scoringVersion": {
611
618
  "type": "string",
612
619
  "pattern": "^sha256:[0-9a-f]{64}$",
613
- "description": "AD-11: computed by the scorer over the five named inputs below and never caller-supplied."
620
+ "description": "AD-11: computed by the scorer over the six named inputs below and never caller-supplied."
614
621
  },
615
622
  "scoringVersionInputs": {
616
623
  "type": "object",
@@ -639,6 +646,11 @@
639
646
  "type": "string",
640
647
  "pattern": "^sha256:[0-9a-f]{64}$",
641
648
  "description": "AD-27 digest: \"sha256:\" plus 64 lowercase hexadecimal characters."
649
+ },
650
+ "mode": {
651
+ "type": "string",
652
+ "const": "contract-scoring",
653
+ "description": "Owed item 4's identity clause: mode enters AD-11's scoring version, superseding AD-11's five-field sentence. Read from the sealed run record, never re-derived, so two runs scored under one mode never collide with a version computed for the other. Required, not optional, which makes this the evidence artifact's `schemaVersion` 1 -> 2 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\". A version-1 artifact carries five scoring-version inputs where this one carries six, so it does not parse, and no version computed before the bump compares with one computed after it."
642
654
  }
643
655
  },
644
656
  "required": [
@@ -646,7 +658,8 @@
646
658
  "corpusDigest",
647
659
  "fixtureDigest",
648
660
  "evaluatorConfigurationDigest",
649
- "scoringPolicyDigest"
661
+ "scoringPolicyDigest",
662
+ "mode"
650
663
  ],
651
664
  "additionalProperties": false
652
665
  },
@@ -686,10 +699,11 @@
686
699
  "corpusDigest",
687
700
  "fixtureDigest",
688
701
  "evaluatorConfigurationDigest",
689
- "scoringPolicyDigest"
702
+ "scoringPolicyDigest",
703
+ "mode"
690
704
  ]
691
705
  },
692
- "description": "Which of the five scoring-version inputs were caller-attested rather than computed by this package. An enum over the five key names rather than free strings, because AD-32 requires the artifact to state *which* inputs were attested and an unconstrained string cannot be checked against anything. AD-11 names three of the five as caller-attested; the enum admits any subset so a stricter or looser integration stays representable."
706
+ "description": "Which of the six scoring-version inputs were caller-attested rather than computed by this package. An enum over the six key names rather than free strings, because AD-32 requires the artifact to state *which* inputs were attested and an unconstrained string cannot be checked against anything. AD-11 names three of the six as caller-attested; the enum admits any subset so a stricter or looser integration stays representable. `mode` is the one member that is not a choice: `ScoringVersionInputs.mode` is read from the sealed run record and never re-derived, so a list omitting it is a misdeclaration rather than a stricter integration. The schema admits that shape and the constraint ledger records why; `core/emit` always names it."
693
707
  },
694
708
  "trials": {
695
709
  "type": "object",
@@ -1123,6 +1137,108 @@
1123
1137
  "contractVerdict": {
1124
1138
  "$ref": "#/$defs/Verdict"
1125
1139
  },
1140
+ "uncitedFindingGaps": {
1141
+ "type": "array",
1142
+ "items": {
1143
+ "type": "object",
1144
+ "properties": {
1145
+ "findingId": {
1146
+ "type": "string",
1147
+ "pattern": "^F-[0-9]{3,}$"
1148
+ },
1149
+ "observationIds": {
1150
+ "minItems": 1,
1151
+ "type": "array",
1152
+ "items": {
1153
+ "type": "string",
1154
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
1155
+ "description": "A kebab-case slug. Excludes \"/\" and \"~\" so an identifier can be embedded in an interaction-rooted pointer without escaping."
1156
+ }
1157
+ },
1158
+ "quotedEvidence": {
1159
+ "minItems": 1,
1160
+ "type": "array",
1161
+ "items": {
1162
+ "anyOf": [
1163
+ {
1164
+ "type": "object",
1165
+ "properties": {
1166
+ "quote": {
1167
+ "type": "string",
1168
+ "minLength": 1,
1169
+ "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.\""
1170
+ },
1171
+ "channel": {
1172
+ "type": "string",
1173
+ "const": "artifact"
1174
+ },
1175
+ "artifactId": {
1176
+ "type": "string",
1177
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
1178
+ "description": "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."
1179
+ }
1180
+ },
1181
+ "required": [
1182
+ "quote",
1183
+ "channel",
1184
+ "artifactId"
1185
+ ],
1186
+ "additionalProperties": false
1187
+ },
1188
+ {
1189
+ "type": "object",
1190
+ "properties": {
1191
+ "quote": {
1192
+ "type": "string",
1193
+ "minLength": 1,
1194
+ "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.\""
1195
+ },
1196
+ "channel": {
1197
+ "type": "string",
1198
+ "enum": [
1199
+ "response-body",
1200
+ "response-headers",
1201
+ "response-status",
1202
+ "call-inputs",
1203
+ "stdout",
1204
+ "stderr",
1205
+ "exit-code"
1206
+ ]
1207
+ },
1208
+ "artifactId": {
1209
+ "type": "null",
1210
+ "description": "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."
1211
+ }
1212
+ },
1213
+ "required": [
1214
+ "quote",
1215
+ "channel",
1216
+ "artifactId"
1217
+ ],
1218
+ "additionalProperties": false
1219
+ }
1220
+ ]
1221
+ }
1222
+ },
1223
+ "severity": {
1224
+ "type": "string",
1225
+ "enum": [
1226
+ "low",
1227
+ "material",
1228
+ "critical"
1229
+ ]
1230
+ }
1231
+ },
1232
+ "required": [
1233
+ "findingId",
1234
+ "observationIds",
1235
+ "quotedEvidence",
1236
+ "severity"
1237
+ ],
1238
+ "additionalProperties": false
1239
+ },
1240
+ "description": "Owed item 5's rung record, contract-scoring only: one entry per uncited `defect` finding, per `core/score/outcome.ts`'s `uncitedDefectFindingGaps`. Required, not optional, which makes this the `schemaVersion` 2 -> 3 BREAKING bump under AD-11: an empty array is legal and is what a run with no uncited defect finding carries, but the key itself must be present. Never on the production branch, where the ladder signal alone is enough and this key would fail `strictObject`'s `unrecognized_keys` rule."
1241
+ },
1126
1242
  "systemRecommendationRecorded": {
1127
1243
  "description": "The evaluator's recommendation about the SYSTEM, recorded and never promoted. On a knowingly defective probe a system-directed FAIL is an input rather than a signal about the contract.",
1128
1244
  "$ref": "#/$defs/EvaluatorRecommendation"
@@ -1158,6 +1274,7 @@
1158
1274
  "remediation",
1159
1275
  "mode",
1160
1276
  "contractVerdict",
1277
+ "uncitedFindingGaps",
1161
1278
  "systemRecommendationRecorded",
1162
1279
  "systemRecommendationNote"
1163
1280
  ],
@@ -1165,7 +1282,7 @@
1165
1282
  "description": "Contract-scoring mode: the verdict is about the contract, and the evaluator's recommendation about the system is recorded beside it rather than promoted."
1166
1283
  }
1167
1284
  ],
1168
- "description": "The scored output, owned by `emit` per AD-24, with no prior art; `score` produces the outcome and verdict values it serializes. The two modes are separate branches because AD-21 requires that the production verdict and the contract verdict never share a field. This expresses that settled sentence and no more: Owed item 4's remaining half stays open, namely mode being fixed before ingest and entering AD-11's identity inputs rather than appearing first here; and the Sealed Run Record still carries no mode.",
1285
+ "description": "The scored output, owned by `emit` per AD-24, with no prior art; `score` produces the outcome and verdict values it serializes. The two modes are separate branches because AD-21 requires that the production verdict and the contract verdict never share a field. Mode is no longer first stated here: the Sealed Run Record now carries a required `mode`, where AD-21's \"fixed before ingest\" puts it, so this artifact restates a mode the sealed record already fixed and is never the source. Owed item 4 is closed as of this schemaVersion: `mode` is `ScoringVersionInputs`'s sixth field, `core/score/ladder.ts` carries `ProductionAssessment`/`ContractAssessment` and their own total ladders, and `core/score/mode-agreement.ts` rejects a `production` record paired with a `contract-scoring` artifact in both directions as an AD-32 cross-artifact disagreement. That check is a hand-written function at the assembly boundary rather than a schema refinement, since no single schema sees both artifacts; `emit` is its one caller, immediately before returning the artifact it just built. Owed item 5 is closed as of this schemaVersion too: the contract-scoring branch carries a required `uncitedFindingGaps`, and both ladders in `core/score/ladder.ts` gain a shared `uncited-defect-finding` CONCERNS row over `AssessmentCommon.uncitedDefectFindings`, so an ingested defect finding citing no oracle now resolves at least CONCERNS instead of routing nowhere.",
1169
1286
  "$defs": {
1170
1287
  "CheckResolution": {
1171
1288
  "description": "One node of an oracle's `check` tree as it resolved. AD-4's resolution is three-valued rather than two, and the introduction vocabulary has exactly one member because AD-4 closes the introduction set at one: an empty collection. `null` where the resolution is not `insufficient-evidence`. A leaf carries an empty `children` array.",
@@ -35,7 +35,7 @@
35
35
  "contractId": {
36
36
  "type": "string",
37
37
  "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
38
- "description": "The prior art's `taskId`, renamed. \"Task\" is experiment vocabulary with no product meaning, and the manifest keeps an identifier because it is the artifact `core/ingest` matches against a run; the run record and the probe pin what they describe by digest instead."
38
+ "description": "The prior art's `taskId`, renamed. \"Task\" is experiment vocabulary with no product meaning, and the manifest keeps an identifier so a reader can say which contract the run was isolated for. It is a label and not a second operand for any check: `core/ingest` matches this artifact to a run on `runId`, `contractDigest`, and `evaluatorConfigurationDigest`, which is the whole of the agreement the two artifacts make. Nothing in the pipeline carries a contract identifier to compare this against, since the sealed run record pins its contract by digest and the eval contract is not among ingest's inputs."
39
39
  },
40
40
  "conditionArm": {
41
41
  "type": "string",
@@ -68,38 +68,44 @@
68
68
  "allowedMounts": {
69
69
  "type": "array",
70
70
  "items": {
71
- "type": "string"
71
+ "type": "string",
72
+ "minLength": 1
72
73
  }
73
74
  },
74
75
  "observedMounts": {
75
76
  "type": "array",
76
77
  "items": {
77
- "type": "string"
78
+ "type": "string",
79
+ "minLength": 1
78
80
  },
79
- "description": "Observed mounts, network targets, and tool calls exceeding their allowlist is a violation AD-16 has `core/ingest` record; it is a cross-field rule with no AD-5 code and the schema admits it."
81
+ "description": "Observed mounts, network targets, and tool calls exceeding their allowlist is a violation AD-16 has `core/ingest` record; it is a cross-field rule with no AD-5 code and the schema admits it. Each entry is non-empty: an empty string is not a mount, and it renders as a basis line naming nothing after its colon."
80
82
  },
81
83
  "networkAllowlist": {
82
84
  "type": "array",
83
85
  "items": {
84
- "type": "string"
86
+ "type": "string",
87
+ "minLength": 1
85
88
  }
86
89
  },
87
90
  "observedNetworkTargets": {
88
91
  "type": "array",
89
92
  "items": {
90
- "type": "string"
93
+ "type": "string",
94
+ "minLength": 1
91
95
  }
92
96
  },
93
97
  "toolAllowlist": {
94
98
  "type": "array",
95
99
  "items": {
96
- "type": "string"
100
+ "type": "string",
101
+ "minLength": 1
97
102
  }
98
103
  },
99
104
  "observedToolCalls": {
100
105
  "type": "array",
101
106
  "items": {
102
- "type": "string"
107
+ "type": "string",
108
+ "minLength": 1
103
109
  }
104
110
  },
105
111
  "resourceCeilings": {
@@ -357,13 +363,14 @@
357
363
  "violation": {
358
364
  "anyOf": [
359
365
  {
360
- "type": "string"
366
+ "type": "string",
367
+ "minLength": 1
361
368
  },
362
369
  {
363
370
  "type": "null"
364
371
  }
365
372
  ],
366
- "description": "The sixteenth of the prior art's sixteen required members, and the one that is not a description of the run: a non-null violation invalidates it. AD-16 says the schema is \"seeded from the prior art's fifteen\"; the prior art's `required` array has sixteen. Settled by construction: the fifteen are the fields describing the run and this is the invalidation outcome. All sixteen are carried."
373
+ "description": "The sixteenth of the prior art's sixteen required members, and the one that is not a description of the run: a non-null violation invalidates it. Non-empty when present, on `QuotedEvidence.quote`'s precedent: `null` is the spelling for no violation, so an empty string is a violation that names nothing while still invalidating the run and rendering a blank basis entry. AD-16 says the schema is \"seeded from the prior art's fifteen\"; the prior art's `required` array has sixteen. Settled by construction: the fifteen are the fields describing the run and this is the invalidation outcome. All sixteen are carried."
367
374
  }
368
375
  },
369
376
  "required": [