overseer-testing-protocol 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +19 -0
  3. data/README.md +75 -0
  4. data/SOURCE.json +6 -0
  5. data/bin/overseer-testing-conformance +53 -0
  6. data/docs/testing-control-implementation-guide.md +116 -0
  7. data/docs/testing-control-protocol.md +432 -0
  8. data/lib/overseer/testing_control/conformance/case_file.rb +120 -0
  9. data/lib/overseer/testing_control/conformance/http_transport.rb +114 -0
  10. data/lib/overseer/testing_control/conformance/report.rb +104 -0
  11. data/lib/overseer/testing_control/conformance/runner.rb +783 -0
  12. data/lib/overseer/testing_control/discovery.rb +79 -0
  13. data/lib/overseer/testing_control/json_subset_matcher.rb +120 -0
  14. data/lib/overseer/testing_control/protocol_v3.rb +298 -0
  15. data/lib/overseer/testing_control/redaction.rb +111 -0
  16. data/lib/overseer/testing_protocol.rb +9 -0
  17. data/protocol/testing-control/v3/conformance-case.schema.json +151 -0
  18. data/protocol/testing-control/v3/conformance-report.schema.json +255 -0
  19. data/protocol/testing-control/v3/fixtures/capabilities-response.json +147 -0
  20. data/protocol/testing-control/v3/fixtures/conformance-case.json +23 -0
  21. data/protocol/testing-control/v3/fixtures/conformance-report.json +88 -0
  22. data/protocol/testing-control/v3/fixtures/error-response.json +20 -0
  23. data/protocol/testing-control/v3/fixtures/manifest.json +13 -0
  24. data/protocol/testing-control/v3/fixtures/probe-request.json +20 -0
  25. data/protocol/testing-control/v3/fixtures/probe-response.json +22 -0
  26. data/protocol/testing-control/v3/fixtures/reset-response.json +15 -0
  27. data/protocol/testing-control/v3/fixtures/sink-query-request.json +26 -0
  28. data/protocol/testing-control/v3/fixtures/sink-query-response.json +39 -0
  29. data/protocol/testing-control/v3/fixtures/state-request.json +20 -0
  30. data/protocol/testing-control/v3/fixtures/state-response.json +23 -0
  31. data/protocol/testing-control/v3/openapi.yaml +343 -0
  32. data/protocol/testing-control/v3/schema.json +772 -0
  33. metadata +85 -0
@@ -0,0 +1,772 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:overseer:testing-control:v3",
4
+ "title": "Overseer testing-control protocol v3",
5
+ "description": "Normative request and response bodies for Overseer's product-agnostic testing-control protocol.",
6
+ "$defs": {
7
+ "protocol": {
8
+ "type": "object",
9
+ "additionalProperties": false,
10
+ "required": ["name", "version"],
11
+ "properties": {
12
+ "name": {
13
+ "const": "overseer-testing-control"
14
+ },
15
+ "version": {
16
+ "const": "3"
17
+ }
18
+ }
19
+ },
20
+ "identifier": {
21
+ "type": "string",
22
+ "minLength": 1,
23
+ "maxLength": 128,
24
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]*$"
25
+ },
26
+ "capabilityId": {
27
+ "type": "string",
28
+ "minLength": 1,
29
+ "maxLength": 96,
30
+ "pattern": "^[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*)*$"
31
+ },
32
+ "capabilityVersion": {
33
+ "type": "string",
34
+ "minLength": 1,
35
+ "maxLength": 32,
36
+ "pattern": "^[1-9][0-9]*$"
37
+ },
38
+ "timestamp": {
39
+ "type": "string",
40
+ "format": "date-time"
41
+ },
42
+ "metadata": {
43
+ "type": "object",
44
+ "maxProperties": 64,
45
+ "additionalProperties": {
46
+ "type": ["string", "number", "integer", "boolean", "null"]
47
+ }
48
+ },
49
+ "jsonObject": {
50
+ "type": "object"
51
+ },
52
+ "jsonSchema": {
53
+ "type": "object",
54
+ "required": ["$schema", "type"],
55
+ "properties": {
56
+ "$schema": {
57
+ "const": "https://json-schema.org/draft/2020-12/schema"
58
+ },
59
+ "type": {
60
+ "const": "object"
61
+ }
62
+ }
63
+ },
64
+ "meta": {
65
+ "type": "object",
66
+ "additionalProperties": false,
67
+ "required": ["runId", "correlationId"],
68
+ "properties": {
69
+ "runId": {
70
+ "$ref": "#/$defs/identifier"
71
+ },
72
+ "correlationId": {
73
+ "$ref": "#/$defs/identifier"
74
+ },
75
+ "stepId": {
76
+ "$ref": "#/$defs/identifier"
77
+ }
78
+ }
79
+ },
80
+ "capabilityReference": {
81
+ "type": "object",
82
+ "additionalProperties": false,
83
+ "required": ["id", "version"],
84
+ "properties": {
85
+ "id": {
86
+ "$ref": "#/$defs/capabilityId"
87
+ },
88
+ "version": {
89
+ "$ref": "#/$defs/capabilityVersion"
90
+ }
91
+ }
92
+ },
93
+ "resetGuarantees": {
94
+ "type": "object",
95
+ "additionalProperties": false,
96
+ "required": ["strategy", "clearsSinks"],
97
+ "properties": {
98
+ "strategy": {
99
+ "enum": ["in-process", "runtime-restart"]
100
+ },
101
+ "clearsSinks": {
102
+ "const": true
103
+ }
104
+ }
105
+ },
106
+ "limits": {
107
+ "type": "object",
108
+ "additionalProperties": false,
109
+ "required": [
110
+ "maxRequestBytes",
111
+ "maxResponseBytes",
112
+ "maxSchemaBytes",
113
+ "maxSinkRecordsPerQuery",
114
+ "maxSinkRecordBytes"
115
+ ],
116
+ "properties": {
117
+ "maxRequestBytes": {
118
+ "type": "integer",
119
+ "minimum": 1024,
120
+ "maximum": 16777216
121
+ },
122
+ "maxResponseBytes": {
123
+ "type": "integer",
124
+ "minimum": 1024,
125
+ "maximum": 16777216
126
+ },
127
+ "maxSchemaBytes": {
128
+ "type": "integer",
129
+ "minimum": 1024,
130
+ "maximum": 1048576
131
+ },
132
+ "maxSinkRecordsPerQuery": {
133
+ "type": "integer",
134
+ "minimum": 1,
135
+ "maximum": 1000
136
+ },
137
+ "maxSinkRecordBytes": {
138
+ "type": "integer",
139
+ "minimum": 256,
140
+ "maximum": 1048576
141
+ }
142
+ }
143
+ },
144
+ "safety": {
145
+ "type": "object",
146
+ "additionalProperties": false,
147
+ "required": [
148
+ "syntheticDataRequired",
149
+ "realCredentialsAllowed",
150
+ "secretPersistenceAllowed",
151
+ "externalNetwork"
152
+ ],
153
+ "properties": {
154
+ "syntheticDataRequired": {
155
+ "const": true
156
+ },
157
+ "realCredentialsAllowed": {
158
+ "const": false
159
+ },
160
+ "secretPersistenceAllowed": {
161
+ "const": false
162
+ },
163
+ "externalNetwork": {
164
+ "enum": ["blocked", "allowlisted"]
165
+ }
166
+ }
167
+ },
168
+ "stateCapability": {
169
+ "type": "object",
170
+ "additionalProperties": false,
171
+ "required": ["id", "version", "title", "idempotency", "inputSchema", "outputSchema"],
172
+ "properties": {
173
+ "id": {
174
+ "$ref": "#/$defs/capabilityId"
175
+ },
176
+ "version": {
177
+ "$ref": "#/$defs/capabilityVersion"
178
+ },
179
+ "title": {
180
+ "type": "string",
181
+ "minLength": 1,
182
+ "maxLength": 160
183
+ },
184
+ "description": {
185
+ "type": "string",
186
+ "minLength": 1,
187
+ "maxLength": 1000
188
+ },
189
+ "idempotency": {
190
+ "enum": ["required", "supported", "none"]
191
+ },
192
+ "inputSchema": {
193
+ "$ref": "#/$defs/jsonSchema"
194
+ },
195
+ "outputSchema": {
196
+ "$ref": "#/$defs/jsonSchema"
197
+ }
198
+ }
199
+ },
200
+ "probeCapability": {
201
+ "type": "object",
202
+ "additionalProperties": false,
203
+ "required": ["id", "version", "title", "readOnly", "inputSchema", "outputSchema"],
204
+ "properties": {
205
+ "id": {
206
+ "$ref": "#/$defs/capabilityId"
207
+ },
208
+ "version": {
209
+ "$ref": "#/$defs/capabilityVersion"
210
+ },
211
+ "title": {
212
+ "type": "string",
213
+ "minLength": 1,
214
+ "maxLength": 160
215
+ },
216
+ "description": {
217
+ "type": "string",
218
+ "minLength": 1,
219
+ "maxLength": 1000
220
+ },
221
+ "readOnly": {
222
+ "const": true
223
+ },
224
+ "inputSchema": {
225
+ "$ref": "#/$defs/jsonSchema"
226
+ },
227
+ "outputSchema": {
228
+ "$ref": "#/$defs/jsonSchema"
229
+ }
230
+ }
231
+ },
232
+ "sinkCapability": {
233
+ "type": "object",
234
+ "additionalProperties": false,
235
+ "required": [
236
+ "id",
237
+ "version",
238
+ "title",
239
+ "effectKinds",
240
+ "outcomes",
241
+ "queryInputSchema",
242
+ "recordSchema"
243
+ ],
244
+ "properties": {
245
+ "id": {
246
+ "$ref": "#/$defs/capabilityId"
247
+ },
248
+ "version": {
249
+ "$ref": "#/$defs/capabilityVersion"
250
+ },
251
+ "title": {
252
+ "type": "string",
253
+ "minLength": 1,
254
+ "maxLength": 160
255
+ },
256
+ "description": {
257
+ "type": "string",
258
+ "minLength": 1,
259
+ "maxLength": 1000
260
+ },
261
+ "effectKinds": {
262
+ "type": "array",
263
+ "minItems": 1,
264
+ "uniqueItems": true,
265
+ "items": {
266
+ "enum": [
267
+ "email",
268
+ "sms",
269
+ "webhook",
270
+ "document-delivery",
271
+ "integration-command",
272
+ "custom"
273
+ ]
274
+ }
275
+ },
276
+ "outcomes": {
277
+ "type": "array",
278
+ "minItems": 1,
279
+ "uniqueItems": true,
280
+ "items": {
281
+ "$ref": "#/$defs/capabilityId"
282
+ }
283
+ },
284
+ "queryInputSchema": {
285
+ "$ref": "#/$defs/jsonSchema"
286
+ },
287
+ "recordSchema": {
288
+ "$ref": "#/$defs/jsonSchema"
289
+ }
290
+ }
291
+ },
292
+ "capabilitiesData": {
293
+ "type": "object",
294
+ "additionalProperties": false,
295
+ "required": [
296
+ "application",
297
+ "environment",
298
+ "reset",
299
+ "features",
300
+ "limits",
301
+ "safety",
302
+ "states",
303
+ "probes",
304
+ "sinks"
305
+ ],
306
+ "properties": {
307
+ "application": {
308
+ "type": "object",
309
+ "additionalProperties": false,
310
+ "required": ["id", "version"],
311
+ "properties": {
312
+ "id": {
313
+ "$ref": "#/$defs/capabilityId"
314
+ },
315
+ "version": {
316
+ "type": "string",
317
+ "minLength": 1,
318
+ "maxLength": 128
319
+ }
320
+ }
321
+ },
322
+ "environment": {
323
+ "type": "object",
324
+ "additionalProperties": false,
325
+ "required": ["id", "kind", "isolated"],
326
+ "properties": {
327
+ "id": {
328
+ "$ref": "#/$defs/identifier"
329
+ },
330
+ "kind": {
331
+ "const": "test"
332
+ },
333
+ "isolated": {
334
+ "const": true
335
+ }
336
+ }
337
+ },
338
+ "reset": {
339
+ "$ref": "#/$defs/resetGuarantees"
340
+ },
341
+ "features": {
342
+ "type": "array",
343
+ "minItems": 5,
344
+ "uniqueItems": true,
345
+ "items": {
346
+ "enum": [
347
+ "correlation-propagation",
348
+ "deterministic-replay",
349
+ "reset",
350
+ "schema-validation",
351
+ "sink-clearing"
352
+ ]
353
+ }
354
+ },
355
+ "limits": {
356
+ "$ref": "#/$defs/limits"
357
+ },
358
+ "safety": {
359
+ "$ref": "#/$defs/safety"
360
+ },
361
+ "states": {
362
+ "type": "array",
363
+ "items": {
364
+ "$ref": "#/$defs/stateCapability"
365
+ }
366
+ },
367
+ "probes": {
368
+ "type": "array",
369
+ "items": {
370
+ "$ref": "#/$defs/probeCapability"
371
+ }
372
+ },
373
+ "sinks": {
374
+ "type": "array",
375
+ "items": {
376
+ "$ref": "#/$defs/sinkCapability"
377
+ }
378
+ }
379
+ }
380
+ },
381
+ "capabilitiesResponse": {
382
+ "type": "object",
383
+ "additionalProperties": false,
384
+ "required": ["protocol", "meta", "data"],
385
+ "properties": {
386
+ "protocol": {
387
+ "$ref": "#/$defs/protocol"
388
+ },
389
+ "meta": {
390
+ "$ref": "#/$defs/meta"
391
+ },
392
+ "data": {
393
+ "$ref": "#/$defs/capabilitiesData"
394
+ }
395
+ }
396
+ },
397
+ "resetData": {
398
+ "type": "object",
399
+ "additionalProperties": false,
400
+ "required": ["resetAt", "strategy", "sinksCleared"],
401
+ "properties": {
402
+ "resetAt": {
403
+ "$ref": "#/$defs/timestamp"
404
+ },
405
+ "strategy": {
406
+ "enum": ["in-process", "runtime-restart"]
407
+ },
408
+ "sinksCleared": {
409
+ "const": true
410
+ }
411
+ }
412
+ },
413
+ "resetResponse": {
414
+ "type": "object",
415
+ "additionalProperties": false,
416
+ "required": ["protocol", "meta", "data"],
417
+ "properties": {
418
+ "protocol": {
419
+ "$ref": "#/$defs/protocol"
420
+ },
421
+ "meta": {
422
+ "$ref": "#/$defs/meta"
423
+ },
424
+ "data": {
425
+ "$ref": "#/$defs/resetData"
426
+ }
427
+ }
428
+ },
429
+ "stateRequestData": {
430
+ "type": "object",
431
+ "additionalProperties": false,
432
+ "required": ["capability", "input"],
433
+ "properties": {
434
+ "capability": {
435
+ "$ref": "#/$defs/capabilityReference"
436
+ },
437
+ "input": {
438
+ "$ref": "#/$defs/jsonObject"
439
+ }
440
+ }
441
+ },
442
+ "stateRequest": {
443
+ "type": "object",
444
+ "additionalProperties": false,
445
+ "required": ["protocol", "meta", "data"],
446
+ "properties": {
447
+ "protocol": {
448
+ "$ref": "#/$defs/protocol"
449
+ },
450
+ "meta": {
451
+ "$ref": "#/$defs/meta"
452
+ },
453
+ "data": {
454
+ "$ref": "#/$defs/stateRequestData"
455
+ }
456
+ }
457
+ },
458
+ "stateResponseData": {
459
+ "type": "object",
460
+ "additionalProperties": false,
461
+ "required": ["capability", "identifiers", "output"],
462
+ "properties": {
463
+ "capability": {
464
+ "$ref": "#/$defs/capabilityReference"
465
+ },
466
+ "identifiers": {
467
+ "type": "object",
468
+ "minProperties": 1,
469
+ "maxProperties": 64,
470
+ "additionalProperties": {
471
+ "type": ["string", "integer"]
472
+ }
473
+ },
474
+ "output": {
475
+ "$ref": "#/$defs/jsonObject"
476
+ }
477
+ }
478
+ },
479
+ "stateResponse": {
480
+ "type": "object",
481
+ "additionalProperties": false,
482
+ "required": ["protocol", "meta", "data"],
483
+ "properties": {
484
+ "protocol": {
485
+ "$ref": "#/$defs/protocol"
486
+ },
487
+ "meta": {
488
+ "$ref": "#/$defs/meta"
489
+ },
490
+ "data": {
491
+ "$ref": "#/$defs/stateResponseData"
492
+ }
493
+ }
494
+ },
495
+ "probeRequestData": {
496
+ "type": "object",
497
+ "additionalProperties": false,
498
+ "required": ["capability", "input"],
499
+ "properties": {
500
+ "capability": {
501
+ "$ref": "#/$defs/capabilityReference"
502
+ },
503
+ "input": {
504
+ "$ref": "#/$defs/jsonObject"
505
+ }
506
+ }
507
+ },
508
+ "probeRequest": {
509
+ "type": "object",
510
+ "additionalProperties": false,
511
+ "required": ["protocol", "meta", "data"],
512
+ "properties": {
513
+ "protocol": {
514
+ "$ref": "#/$defs/protocol"
515
+ },
516
+ "meta": {
517
+ "$ref": "#/$defs/meta"
518
+ },
519
+ "data": {
520
+ "$ref": "#/$defs/probeRequestData"
521
+ }
522
+ }
523
+ },
524
+ "probeResponseData": {
525
+ "type": "object",
526
+ "additionalProperties": false,
527
+ "required": ["capability", "observedAt", "projection"],
528
+ "properties": {
529
+ "capability": {
530
+ "$ref": "#/$defs/capabilityReference"
531
+ },
532
+ "observedAt": {
533
+ "$ref": "#/$defs/timestamp"
534
+ },
535
+ "projection": {
536
+ "$ref": "#/$defs/jsonObject"
537
+ }
538
+ }
539
+ },
540
+ "probeResponse": {
541
+ "type": "object",
542
+ "additionalProperties": false,
543
+ "required": ["protocol", "meta", "data"],
544
+ "properties": {
545
+ "protocol": {
546
+ "$ref": "#/$defs/protocol"
547
+ },
548
+ "meta": {
549
+ "$ref": "#/$defs/meta"
550
+ },
551
+ "data": {
552
+ "$ref": "#/$defs/probeResponseData"
553
+ }
554
+ }
555
+ },
556
+ "sinkQueryRequestData": {
557
+ "type": "object",
558
+ "additionalProperties": false,
559
+ "required": ["capability", "filter", "input"],
560
+ "properties": {
561
+ "capability": {
562
+ "$ref": "#/$defs/capabilityReference"
563
+ },
564
+ "filter": {
565
+ "type": "object",
566
+ "additionalProperties": false,
567
+ "required": ["correlationId"],
568
+ "properties": {
569
+ "correlationId": {
570
+ "$ref": "#/$defs/identifier"
571
+ },
572
+ "stepId": {
573
+ "$ref": "#/$defs/identifier"
574
+ },
575
+ "effectKinds": {
576
+ "type": "array",
577
+ "minItems": 1,
578
+ "uniqueItems": true,
579
+ "items": {
580
+ "enum": [
581
+ "email",
582
+ "sms",
583
+ "webhook",
584
+ "document-delivery",
585
+ "integration-command",
586
+ "custom"
587
+ ]
588
+ }
589
+ },
590
+ "capturedAfter": {
591
+ "$ref": "#/$defs/timestamp"
592
+ }
593
+ }
594
+ },
595
+ "input": {
596
+ "$ref": "#/$defs/jsonObject"
597
+ },
598
+ "cursor": {
599
+ "type": "string",
600
+ "minLength": 1,
601
+ "maxLength": 1024
602
+ },
603
+ "limit": {
604
+ "type": "integer",
605
+ "minimum": 1,
606
+ "maximum": 1000
607
+ }
608
+ }
609
+ },
610
+ "sinkQueryRequest": {
611
+ "type": "object",
612
+ "additionalProperties": false,
613
+ "required": ["protocol", "meta", "data"],
614
+ "properties": {
615
+ "protocol": {
616
+ "$ref": "#/$defs/protocol"
617
+ },
618
+ "meta": {
619
+ "$ref": "#/$defs/meta"
620
+ },
621
+ "data": {
622
+ "$ref": "#/$defs/sinkQueryRequestData"
623
+ }
624
+ }
625
+ },
626
+ "effectRecord": {
627
+ "type": "object",
628
+ "additionalProperties": false,
629
+ "required": [
630
+ "id",
631
+ "capability",
632
+ "effectKind",
633
+ "correlationId",
634
+ "capturedAt",
635
+ "summary",
636
+ "payload"
637
+ ],
638
+ "properties": {
639
+ "id": {
640
+ "$ref": "#/$defs/identifier"
641
+ },
642
+ "capability": {
643
+ "$ref": "#/$defs/capabilityReference"
644
+ },
645
+ "effectKind": {
646
+ "enum": ["email", "sms", "webhook", "document-delivery", "integration-command", "custom"]
647
+ },
648
+ "outcome": {
649
+ "$ref": "#/$defs/capabilityId"
650
+ },
651
+ "correlationId": {
652
+ "$ref": "#/$defs/identifier"
653
+ },
654
+ "stepId": {
655
+ "$ref": "#/$defs/identifier"
656
+ },
657
+ "capturedAt": {
658
+ "$ref": "#/$defs/timestamp"
659
+ },
660
+ "summary": {
661
+ "type": "string",
662
+ "minLength": 1,
663
+ "maxLength": 500
664
+ },
665
+ "metadata": {
666
+ "$ref": "#/$defs/metadata"
667
+ },
668
+ "payload": {
669
+ "$ref": "#/$defs/jsonObject"
670
+ }
671
+ }
672
+ },
673
+ "sinkQueryResponseData": {
674
+ "type": "object",
675
+ "additionalProperties": false,
676
+ "required": ["capability", "records"],
677
+ "properties": {
678
+ "capability": {
679
+ "$ref": "#/$defs/capabilityReference"
680
+ },
681
+ "records": {
682
+ "type": "array",
683
+ "maxItems": 1000,
684
+ "items": {
685
+ "$ref": "#/$defs/effectRecord"
686
+ }
687
+ },
688
+ "nextCursor": {
689
+ "type": "string",
690
+ "minLength": 1,
691
+ "maxLength": 1024
692
+ }
693
+ }
694
+ },
695
+ "sinkQueryResponse": {
696
+ "type": "object",
697
+ "additionalProperties": false,
698
+ "required": ["protocol", "meta", "data"],
699
+ "properties": {
700
+ "protocol": {
701
+ "$ref": "#/$defs/protocol"
702
+ },
703
+ "meta": {
704
+ "$ref": "#/$defs/meta"
705
+ },
706
+ "data": {
707
+ "$ref": "#/$defs/sinkQueryResponseData"
708
+ }
709
+ }
710
+ },
711
+ "error": {
712
+ "type": "object",
713
+ "additionalProperties": false,
714
+ "required": ["code", "title", "detail", "retryable"],
715
+ "properties": {
716
+ "code": {
717
+ "enum": [
718
+ "invalid-request",
719
+ "capability-not-found",
720
+ "protocol-version-unsupported",
721
+ "reset-requires-restart",
722
+ "payload-too-large",
723
+ "schema-validation-failed",
724
+ "limit-exceeded",
725
+ "runtime-unavailable",
726
+ "internal-error"
727
+ ]
728
+ },
729
+ "title": {
730
+ "type": "string",
731
+ "minLength": 1,
732
+ "maxLength": 160
733
+ },
734
+ "detail": {
735
+ "type": "string",
736
+ "minLength": 1,
737
+ "maxLength": 1000
738
+ },
739
+ "pointer": {
740
+ "type": "string",
741
+ "minLength": 1,
742
+ "maxLength": 500,
743
+ "pattern": "^/"
744
+ },
745
+ "retryable": {
746
+ "type": "boolean"
747
+ }
748
+ }
749
+ },
750
+ "errorResponse": {
751
+ "type": "object",
752
+ "additionalProperties": false,
753
+ "required": ["protocol", "meta", "errors"],
754
+ "properties": {
755
+ "protocol": {
756
+ "$ref": "#/$defs/protocol"
757
+ },
758
+ "meta": {
759
+ "$ref": "#/$defs/meta"
760
+ },
761
+ "errors": {
762
+ "type": "array",
763
+ "minItems": 1,
764
+ "maxItems": 32,
765
+ "items": {
766
+ "$ref": "#/$defs/error"
767
+ }
768
+ }
769
+ }
770
+ }
771
+ }
772
+ }