@crvouga/atlas 0.15.0 → 0.17.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 (54) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/reports/src/attachment-files.d.ts +3 -1
  3. package/dist/reports/src/attachment-files.js +14 -4
  4. package/dist/reports/src/evidence-detail.d.ts +19 -2
  5. package/dist/reports/src/evidence-detail.js +63 -14
  6. package/dist/reports/src/evidence-types.d.ts +53 -0
  7. package/dist/reports/src/layer-merge.js +7 -2
  8. package/dist/reports/src/layer-types.d.ts +1 -1
  9. package/dist/reports/src/publish-checks.js +11 -3
  10. package/dist/reports/src/recording-receipt.d.ts +48 -0
  11. package/dist/reports/src/recording-receipt.js +103 -0
  12. package/dist/reports/src/report-cli.d.ts +1 -1
  13. package/dist/reports/src/report-cli.js +20 -2
  14. package/dist/reports/src/report-status.d.ts +2 -0
  15. package/dist/reports/src/report-status.js +17 -1
  16. package/dist/reports/src/reports-explorer-route.d.ts +8 -0
  17. package/dist/reports/src/reports-route.d.ts +8 -0
  18. package/dist/reports/src/test-catalog.d.ts +24 -3
  19. package/dist/reports/src/test-catalog.js +37 -11
  20. package/dist/schema/src/api.d.ts +232 -0
  21. package/dist/schema/src/api.js +35 -6
  22. package/dist/schema/src/cli-results.d.ts +107 -2
  23. package/dist/schema/src/cli-results.js +11 -3
  24. package/dist/schema/src/layer.d.ts +165 -0
  25. package/dist/schema/src/layer.js +72 -1
  26. package/dist/server/src/app.js +3 -2
  27. package/dist/server/src/llms.js +2 -1
  28. package/dist/server/src/openapi.js +2 -1
  29. package/docs/reference/cli.md +5 -0
  30. package/docs/reference/http-api.md +4 -2
  31. package/docs/reference/reports.md +204 -5
  32. package/docs/reference/schema.md +75 -0
  33. package/docs/rich-evidence.md +29 -0
  34. package/docs/server.md +1 -1
  35. package/llms-full.txt +39 -3
  36. package/package.json +1 -1
  37. package/packages/schema/schemas/check-detail.schema.json +20 -0
  38. package/packages/schema/schemas/effective-delta.schema.json +143 -0
  39. package/packages/schema/schemas/effective-evidence.schema.json +143 -0
  40. package/packages/schema/schemas/evidence-page.schema.json +86 -0
  41. package/packages/schema/schemas/layer-rows.schema.json +57 -0
  42. package/packages/schema/schemas/layer.schema.json +153 -0
  43. package/packages/schema/schemas/publish-checks.schema.json +24 -0
  44. package/packages/schema/schemas/publish-result.schema.json +161 -1
  45. package/packages/schema/schemas/report-run.schema.json +71 -0
  46. package/packages/schema/schemas/report-runs.schema.json +38 -1
  47. package/packages/schema/schemas/report-status.schema.json +104 -0
  48. package/packages/schema/schemas/test-catalog.schema.json +41 -0
  49. package/packages/schema/schemas/test-history.schema.json +82 -0
  50. package/packages/server/openapi.json +830 -4
  51. package/packages/visualizer/src/evidence/marks.tsx +16 -0
  52. package/packages/visualizer/src/explorer/RunsView.tsx +128 -10
  53. package/packages/visualizer/src/explorer/catalog.tsx +16 -6
  54. package/packages/visualizer/src/explorer/search.ts +4 -1
@@ -241,6 +241,10 @@
241
241
  "type": "number",
242
242
  "minimum": 0
243
243
  },
244
+ "recordingExpectation": {
245
+ "description": "`required`: expect a video of this check, and report whether it was published. `not-applicable`: intentionally unrecorded. Absent: no expectation. Never changes the check's status",
246
+ "type": "string"
247
+ },
244
248
  "tags": {
245
249
  "description": "Free labels to filter and group by: smoke, slow, flaky…",
246
250
  "type": "array",
@@ -337,6 +341,10 @@
337
341
  "description": {
338
342
  "type": "string"
339
343
  },
344
+ "omitted": {
345
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
346
+ "type": "string"
347
+ },
340
348
  "tags": {
341
349
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
342
350
  "type": "array",
@@ -572,6 +580,10 @@
572
580
  "description": {
573
581
  "type": "string"
574
582
  },
583
+ "omitted": {
584
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
585
+ "type": "string"
586
+ },
575
587
  "tags": {
576
588
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
577
589
  "type": "array",
@@ -844,6 +856,10 @@
844
856
  "description": {
845
857
  "type": "string"
846
858
  },
859
+ "omitted": {
860
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
861
+ "type": "string"
862
+ },
847
863
  "tags": {
848
864
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
849
865
  "type": "array",
@@ -1051,6 +1067,10 @@
1051
1067
  "description": {
1052
1068
  "type": "string"
1053
1069
  },
1070
+ "omitted": {
1071
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
1072
+ "type": "string"
1073
+ },
1054
1074
  "tags": {
1055
1075
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
1056
1076
  "type": "array",
@@ -1308,6 +1328,10 @@
1308
1328
  "description": {
1309
1329
  "type": "string"
1310
1330
  },
1331
+ "omitted": {
1332
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
1333
+ "type": "string"
1334
+ },
1311
1335
  "tags": {
1312
1336
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
1313
1337
  "type": "array",
@@ -1580,6 +1604,10 @@
1580
1604
  "type": "number",
1581
1605
  "minimum": 0
1582
1606
  },
1607
+ "recordingExpectation": {
1608
+ "description": "`required`: expect a video of this check, and report whether it was published. `not-applicable`: intentionally unrecorded. Absent: no expectation. Never changes the check's status",
1609
+ "type": "string"
1610
+ },
1583
1611
  "tags": {
1584
1612
  "description": "Free labels to filter and group by: smoke, slow, flaky…",
1585
1613
  "type": "array",
@@ -1676,6 +1704,10 @@
1676
1704
  "description": {
1677
1705
  "type": "string"
1678
1706
  },
1707
+ "omitted": {
1708
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
1709
+ "type": "string"
1710
+ },
1679
1711
  "tags": {
1680
1712
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
1681
1713
  "type": "array",
@@ -1911,6 +1943,10 @@
1911
1943
  "description": {
1912
1944
  "type": "string"
1913
1945
  },
1946
+ "omitted": {
1947
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
1948
+ "type": "string"
1949
+ },
1914
1950
  "tags": {
1915
1951
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
1916
1952
  "type": "array",
@@ -2183,6 +2219,10 @@
2183
2219
  "description": {
2184
2220
  "type": "string"
2185
2221
  },
2222
+ "omitted": {
2223
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
2224
+ "type": "string"
2225
+ },
2186
2226
  "tags": {
2187
2227
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
2188
2228
  "type": "array",
@@ -2390,6 +2430,10 @@
2390
2430
  "description": {
2391
2431
  "type": "string"
2392
2432
  },
2433
+ "omitted": {
2434
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
2435
+ "type": "string"
2436
+ },
2393
2437
  "tags": {
2394
2438
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
2395
2439
  "type": "array",
@@ -2717,6 +2761,111 @@
2717
2761
  "additionalProperties": {}
2718
2762
  }
2719
2763
  },
2764
+ "recordings": {
2765
+ "description": "Which expected recordings were published. Absent: the producer expected none, or predates this field; a reader reports Unknown",
2766
+ "type": "object",
2767
+ "properties": {
2768
+ "expected": {
2769
+ "type": "integer",
2770
+ "minimum": 0,
2771
+ "maximum": 9007199254740991,
2772
+ "description": "Checks that required a recording: uploaded + referenced + skipped + unresolved"
2773
+ },
2774
+ "uploaded": {
2775
+ "type": "integer",
2776
+ "minimum": 0,
2777
+ "maximum": 9007199254740991
2778
+ },
2779
+ "referenced": {
2780
+ "type": "integer",
2781
+ "minimum": 0,
2782
+ "maximum": 9007199254740991
2783
+ },
2784
+ "skipped": {
2785
+ "type": "integer",
2786
+ "minimum": 0,
2787
+ "maximum": 9007199254740991
2788
+ },
2789
+ "unresolved": {
2790
+ "type": "integer",
2791
+ "minimum": 0,
2792
+ "maximum": 9007199254740991
2793
+ },
2794
+ "notApplicable": {
2795
+ "type": "integer",
2796
+ "minimum": 0,
2797
+ "maximum": 9007199254740991,
2798
+ "description": "Checks intentionally unrecorded. They are not expected and not missing"
2799
+ },
2800
+ "items": {
2801
+ "type": "array",
2802
+ "items": {
2803
+ "type": "object",
2804
+ "properties": {
2805
+ "check": {
2806
+ "type": "string",
2807
+ "minLength": 1,
2808
+ "description": "The id of the check"
2809
+ },
2810
+ "state": {
2811
+ "type": "string",
2812
+ "minLength": 1
2813
+ },
2814
+ "reason": {
2815
+ "description": "Why the recording is not uploaded. Never contains a path, a token or payload data",
2816
+ "type": "string"
2817
+ },
2818
+ "files": {
2819
+ "description": "Every video attachment of the check, at any level",
2820
+ "type": "array",
2821
+ "items": {
2822
+ "type": "object",
2823
+ "properties": {
2824
+ "name": {
2825
+ "type": "string"
2826
+ },
2827
+ "state": {
2828
+ "type": "string"
2829
+ },
2830
+ "bytes": {
2831
+ "type": "integer",
2832
+ "minimum": 0,
2833
+ "maximum": 9007199254740991
2834
+ },
2835
+ "sha256": {
2836
+ "description": "The checksum of the stored bytes: proof the layer holds this exact file",
2837
+ "type": "string"
2838
+ },
2839
+ "reason": {
2840
+ "type": "string"
2841
+ }
2842
+ },
2843
+ "required": [
2844
+ "name"
2845
+ ],
2846
+ "additionalProperties": {}
2847
+ }
2848
+ }
2849
+ },
2850
+ "required": [
2851
+ "check",
2852
+ "state"
2853
+ ],
2854
+ "additionalProperties": {}
2855
+ }
2856
+ }
2857
+ },
2858
+ "required": [
2859
+ "expected",
2860
+ "uploaded",
2861
+ "referenced",
2862
+ "skipped",
2863
+ "unresolved",
2864
+ "notApplicable",
2865
+ "items"
2866
+ ],
2867
+ "additionalProperties": {}
2868
+ },
2720
2869
  "tags": {
2721
2870
  "description": "Free labels to filter and group by: smoke, slow, flaky…",
2722
2871
  "type": "array",
@@ -2813,6 +2962,10 @@
2813
2962
  "description": {
2814
2963
  "type": "string"
2815
2964
  },
2965
+ "omitted": {
2966
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
2967
+ "type": "string"
2968
+ },
2816
2969
  "tags": {
2817
2970
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
2818
2971
  "type": "array",
@@ -73,6 +73,10 @@
73
73
  "type": "number",
74
74
  "minimum": 0
75
75
  },
76
+ "recordingExpectation": {
77
+ "description": "`required`: expect a video of this check, and report whether it was published. `not-applicable`: intentionally unrecorded. Absent: no expectation. Never changes the check's status",
78
+ "type": "string"
79
+ },
76
80
  "tags": {
77
81
  "description": "Free labels to filter and group by: smoke, slow, flaky…",
78
82
  "type": "array",
@@ -169,6 +173,10 @@
169
173
  "description": {
170
174
  "type": "string"
171
175
  },
176
+ "omitted": {
177
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
178
+ "type": "string"
179
+ },
172
180
  "tags": {
173
181
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
174
182
  "type": "array",
@@ -413,6 +421,10 @@
413
421
  "description": {
414
422
  "type": "string"
415
423
  },
424
+ "omitted": {
425
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
426
+ "type": "string"
427
+ },
416
428
  "tags": {
417
429
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
418
430
  "type": "array",
@@ -694,6 +706,10 @@
694
706
  "description": {
695
707
  "type": "string"
696
708
  },
709
+ "omitted": {
710
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
711
+ "type": "string"
712
+ },
697
713
  "tags": {
698
714
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
699
715
  "type": "array",
@@ -911,6 +927,10 @@
911
927
  "description": {
912
928
  "type": "string"
913
929
  },
930
+ "omitted": {
931
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
932
+ "type": "string"
933
+ },
914
934
  "tags": {
915
935
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
916
936
  "type": "array",
@@ -1298,6 +1318,10 @@
1298
1318
  "description": {
1299
1319
  "type": "string"
1300
1320
  },
1321
+ "omitted": {
1322
+ "description": "Why the producer did not include its bytes, in an open vocabulary: too-large, not-found, not-allowed, over-budget, policy… Present on a metadata-only attachment, so a reader can tell \"left out\" from \"never recorded\"",
1323
+ "type": "string"
1324
+ },
1301
1325
  "tags": {
1302
1326
  "description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
1303
1327
  "type": "array",
@@ -5,7 +5,7 @@
5
5
  "properties": {
6
6
  "ok": {
7
7
  "type": "boolean",
8
- "const": true
8
+ "description": "True when the layer was written. False only with `--require-recordings` when an expected recording is not uploaded (the layer was still written; the exit code is then 1)"
9
9
  },
10
10
  "store": {
11
11
  "type": "string",
@@ -71,6 +71,111 @@
71
71
  "type": "integer",
72
72
  "minimum": 0,
73
73
  "maximum": 9007199254740991
74
+ },
75
+ "recordings": {
76
+ "description": "Present when a check declared a `recordingExpectation`: what became of each expected video, with sizes and checksums of the stored bytes. It describes publication only; the checks keep their results",
77
+ "type": "object",
78
+ "properties": {
79
+ "expected": {
80
+ "type": "integer",
81
+ "minimum": 0,
82
+ "maximum": 9007199254740991,
83
+ "description": "Checks that required a recording: uploaded + referenced + skipped + unresolved"
84
+ },
85
+ "uploaded": {
86
+ "type": "integer",
87
+ "minimum": 0,
88
+ "maximum": 9007199254740991
89
+ },
90
+ "referenced": {
91
+ "type": "integer",
92
+ "minimum": 0,
93
+ "maximum": 9007199254740991
94
+ },
95
+ "skipped": {
96
+ "type": "integer",
97
+ "minimum": 0,
98
+ "maximum": 9007199254740991
99
+ },
100
+ "unresolved": {
101
+ "type": "integer",
102
+ "minimum": 0,
103
+ "maximum": 9007199254740991
104
+ },
105
+ "notApplicable": {
106
+ "type": "integer",
107
+ "minimum": 0,
108
+ "maximum": 9007199254740991,
109
+ "description": "Checks intentionally unrecorded. They are not expected and not missing"
110
+ },
111
+ "items": {
112
+ "type": "array",
113
+ "items": {
114
+ "type": "object",
115
+ "properties": {
116
+ "check": {
117
+ "type": "string",
118
+ "minLength": 1,
119
+ "description": "The id of the check"
120
+ },
121
+ "state": {
122
+ "type": "string",
123
+ "minLength": 1
124
+ },
125
+ "reason": {
126
+ "description": "Why the recording is not uploaded. Never contains a path, a token or payload data",
127
+ "type": "string"
128
+ },
129
+ "files": {
130
+ "description": "Every video attachment of the check, at any level",
131
+ "type": "array",
132
+ "items": {
133
+ "type": "object",
134
+ "properties": {
135
+ "name": {
136
+ "type": "string"
137
+ },
138
+ "state": {
139
+ "type": "string"
140
+ },
141
+ "bytes": {
142
+ "type": "integer",
143
+ "minimum": 0,
144
+ "maximum": 9007199254740991
145
+ },
146
+ "sha256": {
147
+ "description": "The checksum of the stored bytes: proof the layer holds this exact file",
148
+ "type": "string"
149
+ },
150
+ "reason": {
151
+ "type": "string"
152
+ }
153
+ },
154
+ "required": [
155
+ "name"
156
+ ],
157
+ "additionalProperties": {}
158
+ }
159
+ }
160
+ },
161
+ "required": [
162
+ "check",
163
+ "state"
164
+ ],
165
+ "additionalProperties": {}
166
+ }
167
+ }
168
+ },
169
+ "required": [
170
+ "expected",
171
+ "uploaded",
172
+ "referenced",
173
+ "skipped",
174
+ "unresolved",
175
+ "notApplicable",
176
+ "items"
177
+ ],
178
+ "additionalProperties": {}
74
179
  }
75
180
  },
76
181
  "required": [
@@ -142,6 +247,61 @@
142
247
  ],
143
248
  "additionalProperties": {}
144
249
  },
250
+ "recordings": {
251
+ "description": "Present when a check declared a `recordingExpectation`",
252
+ "type": "object",
253
+ "properties": {
254
+ "strict": {
255
+ "type": "boolean",
256
+ "description": "Whether `--require-recordings` was given"
257
+ },
258
+ "complete": {
259
+ "type": "boolean",
260
+ "description": "True when every expected recording is uploaded or referenced"
261
+ },
262
+ "expected": {
263
+ "type": "integer",
264
+ "minimum": 0,
265
+ "maximum": 9007199254740991
266
+ },
267
+ "uploaded": {
268
+ "type": "integer",
269
+ "minimum": 0,
270
+ "maximum": 9007199254740991
271
+ },
272
+ "gaps": {
273
+ "type": "array",
274
+ "items": {
275
+ "type": "object",
276
+ "properties": {
277
+ "check": {
278
+ "type": "string"
279
+ },
280
+ "state": {
281
+ "type": "string"
282
+ },
283
+ "reason": {
284
+ "type": "string"
285
+ }
286
+ },
287
+ "required": [
288
+ "check",
289
+ "state"
290
+ ],
291
+ "additionalProperties": {}
292
+ },
293
+ "description": "Each expected recording that is skipped or unresolved. Retry after fixing it: publishing again reuses the stored files"
294
+ }
295
+ },
296
+ "required": [
297
+ "strict",
298
+ "complete",
299
+ "expected",
300
+ "uploaded",
301
+ "gaps"
302
+ ],
303
+ "additionalProperties": {}
304
+ },
145
305
  "warnings": {
146
306
  "type": "array",
147
307
  "items": {
@@ -140,6 +140,36 @@
140
140
  ],
141
141
  "additionalProperties": {}
142
142
  }
143
+ },
144
+ "videos": {
145
+ "description": "Its videos, from its layers and the last result of each test. Absent when it has none or the report carries no video information",
146
+ "type": "object",
147
+ "properties": {
148
+ "references": {
149
+ "type": "integer",
150
+ "minimum": 0,
151
+ "maximum": 9007199254740991,
152
+ "description": "Every reference to a video; identical bytes referenced twice count twice"
153
+ },
154
+ "recordings": {
155
+ "type": "integer",
156
+ "minimum": 0,
157
+ "maximum": 9007199254740991,
158
+ "description": "Distinct playable recordings"
159
+ },
160
+ "unavailable": {
161
+ "type": "integer",
162
+ "minimum": 0,
163
+ "maximum": 9007199254740991,
164
+ "description": "References that name no bytes"
165
+ }
166
+ },
167
+ "required": [
168
+ "references",
169
+ "recordings",
170
+ "unavailable"
171
+ ],
172
+ "additionalProperties": {}
143
173
  }
144
174
  },
145
175
  "required": [
@@ -212,6 +242,47 @@
212
242
  },
213
243
  "detail": {
214
244
  "type": "string"
245
+ },
246
+ "videos": {
247
+ "description": "Every video its evidence references, with who holds it",
248
+ "type": "array",
249
+ "items": {
250
+ "type": "object",
251
+ "properties": {
252
+ "name": {
253
+ "type": "string",
254
+ "description": "The attachment name"
255
+ },
256
+ "owner": {
257
+ "type": "string",
258
+ "description": "Who holds it: `layer`, `check`, `attempt` or `step`. An open vocabulary: treat an unknown owner as a check"
259
+ },
260
+ "attempt": {
261
+ "description": "The retry attempt that holds it, or that holds the step that does",
262
+ "type": "integer",
263
+ "minimum": 0,
264
+ "maximum": 9007199254740991
265
+ },
266
+ "step": {
267
+ "description": "The name of the step that holds it",
268
+ "type": "string"
269
+ },
270
+ "recording": {
271
+ "description": "What identifies the bytes; references with the same value are one recording. Absent when it cannot be played",
272
+ "type": "string"
273
+ },
274
+ "available": {
275
+ "type": "boolean",
276
+ "description": "False when the reference names no bytes (no bundle key, address or inline text)"
277
+ }
278
+ },
279
+ "required": [
280
+ "name",
281
+ "owner",
282
+ "available"
283
+ ],
284
+ "additionalProperties": {}
285
+ }
215
286
  }
216
287
  },
217
288
  "required": [
@@ -13,7 +13,8 @@
13
13
  "total": {
14
14
  "type": "integer",
15
15
  "minimum": 0,
16
- "maximum": 9007199254740991
16
+ "maximum": 9007199254740991,
17
+ "description": "Runs that matched, before `limit`"
17
18
  },
18
19
  "runs": {
19
20
  "type": "array",
@@ -147,6 +148,36 @@
147
148
  ],
148
149
  "additionalProperties": {}
149
150
  }
151
+ },
152
+ "videos": {
153
+ "description": "Its videos, from its layers and the last result of each test. Absent when it has none or the report carries no video information",
154
+ "type": "object",
155
+ "properties": {
156
+ "references": {
157
+ "type": "integer",
158
+ "minimum": 0,
159
+ "maximum": 9007199254740991,
160
+ "description": "Every reference to a video; identical bytes referenced twice count twice"
161
+ },
162
+ "recordings": {
163
+ "type": "integer",
164
+ "minimum": 0,
165
+ "maximum": 9007199254740991,
166
+ "description": "Distinct playable recordings"
167
+ },
168
+ "unavailable": {
169
+ "type": "integer",
170
+ "minimum": 0,
171
+ "maximum": 9007199254740991,
172
+ "description": "References that name no bytes"
173
+ }
174
+ },
175
+ "required": [
176
+ "references",
177
+ "recordings",
178
+ "unavailable"
179
+ ],
180
+ "additionalProperties": {}
150
181
  }
151
182
  },
152
183
  "required": [
@@ -167,6 +198,12 @@
167
198
  ],
168
199
  "additionalProperties": {}
169
200
  }
201
+ },
202
+ "withVideo": {
203
+ "description": "How many of all runs (before `video` and `limit`) have a playable video recording",
204
+ "type": "integer",
205
+ "minimum": 0,
206
+ "maximum": 9007199254740991
170
207
  }
171
208
  },
172
209
  "required": [