@crvouga/atlas 1.8.0 → 1.9.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.
- package/CHANGELOG.md +7 -1
- package/dist/reports/src/evidence-detail.js +6 -1
- package/dist/reports/src/evidence-types.d.ts +2 -0
- package/dist/reports/src/reliability.d.ts +181 -0
- package/dist/reports/src/reliability.js +294 -0
- package/dist/reports/src/report-index.js +1 -1
- package/dist/reports/src/test-catalog.d.ts +8 -2
- package/dist/reports/src/test-catalog.js +10 -5
- package/dist/schema/src/api.d.ts +226 -0
- package/dist/schema/src/api.js +51 -0
- package/dist/server/src/app.js +15 -0
- package/dist/server/src/llms.js +1 -0
- package/dist/server/src/openapi.js +25 -2
- package/docs/reference/http-api.md +48 -0
- package/docs/reference/reports.md +272 -1
- package/docs/reference/schema.md +11 -0
- package/docs/server.md +18 -0
- package/docs/ui.md +10 -0
- package/llms-full.txt +76 -0
- package/package.json +1 -1
- package/packages/schema/schemas/effective-delta.schema.json +26 -0
- package/packages/schema/schemas/effective-evidence.schema.json +26 -0
- package/packages/schema/schemas/evidence-page.schema.json +13 -0
- package/packages/schema/schemas/layer-rows.schema.json +13 -0
- package/packages/schema/schemas/test-catalog.schema.json +17 -0
- package/packages/schema/schemas/test-history.schema.json +34 -0
- package/packages/schema/schemas/test-reliability.schema.json +629 -0
- package/packages/server/openapi.json +1722 -568
- package/packages/visualizer/src/explorer/Reliability.tsx +337 -0
- package/packages/visualizer/src/explorer/TestDetail.tsx +3 -0
- package/packages/visualizer/src/explorer/catalog.tsx +1 -1
- package/packages/visualizer/src/explorer/search.ts +36 -0
package/dist/schema/src/api.d.ts
CHANGED
|
@@ -121,6 +121,12 @@ export declare const EvidenceSummarySchema: z.ZodObject<{
|
|
|
121
121
|
steps: z.ZodNumber;
|
|
122
122
|
annotations: z.ZodNumber;
|
|
123
123
|
attempts: z.ZodNumber;
|
|
124
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
125
|
+
passed: "passed";
|
|
126
|
+
failed: "failed";
|
|
127
|
+
running: "running";
|
|
128
|
+
"not-run": "not-run";
|
|
129
|
+
}>>>;
|
|
124
130
|
links: z.ZodNumber;
|
|
125
131
|
tags: z.ZodArray<z.ZodString>;
|
|
126
132
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -191,6 +197,12 @@ export declare const LayerHeaderSchema: z.ZodObject<{
|
|
|
191
197
|
steps: z.ZodNumber;
|
|
192
198
|
annotations: z.ZodNumber;
|
|
193
199
|
attempts: z.ZodNumber;
|
|
200
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
201
|
+
passed: "passed";
|
|
202
|
+
failed: "failed";
|
|
203
|
+
running: "running";
|
|
204
|
+
"not-run": "not-run";
|
|
205
|
+
}>>>;
|
|
194
206
|
links: z.ZodNumber;
|
|
195
207
|
tags: z.ZodArray<z.ZodString>;
|
|
196
208
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -272,6 +284,12 @@ export declare const LayerRowSchema: z.ZodObject<{
|
|
|
272
284
|
steps: z.ZodNumber;
|
|
273
285
|
annotations: z.ZodNumber;
|
|
274
286
|
attempts: z.ZodNumber;
|
|
287
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
288
|
+
passed: "passed";
|
|
289
|
+
failed: "failed";
|
|
290
|
+
running: "running";
|
|
291
|
+
"not-run": "not-run";
|
|
292
|
+
}>>>;
|
|
275
293
|
links: z.ZodNumber;
|
|
276
294
|
tags: z.ZodArray<z.ZodString>;
|
|
277
295
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -351,6 +369,12 @@ export declare const LayerRowsSchema: z.ZodObject<{
|
|
|
351
369
|
steps: z.ZodNumber;
|
|
352
370
|
annotations: z.ZodNumber;
|
|
353
371
|
attempts: z.ZodNumber;
|
|
372
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
373
|
+
passed: "passed";
|
|
374
|
+
failed: "failed";
|
|
375
|
+
running: "running";
|
|
376
|
+
"not-run": "not-run";
|
|
377
|
+
}>>>;
|
|
354
378
|
links: z.ZodNumber;
|
|
355
379
|
tags: z.ZodArray<z.ZodString>;
|
|
356
380
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -432,6 +456,12 @@ export declare const LayerEvidenceSchema: z.ZodObject<{
|
|
|
432
456
|
steps: z.ZodNumber;
|
|
433
457
|
annotations: z.ZodNumber;
|
|
434
458
|
attempts: z.ZodNumber;
|
|
459
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
460
|
+
passed: "passed";
|
|
461
|
+
failed: "failed";
|
|
462
|
+
running: "running";
|
|
463
|
+
"not-run": "not-run";
|
|
464
|
+
}>>>;
|
|
435
465
|
links: z.ZodNumber;
|
|
436
466
|
tags: z.ZodArray<z.ZodString>;
|
|
437
467
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -507,6 +537,12 @@ export declare const LayerEvidenceSchema: z.ZodObject<{
|
|
|
507
537
|
steps: z.ZodNumber;
|
|
508
538
|
annotations: z.ZodNumber;
|
|
509
539
|
attempts: z.ZodNumber;
|
|
540
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
541
|
+
passed: "passed";
|
|
542
|
+
failed: "failed";
|
|
543
|
+
running: "running";
|
|
544
|
+
"not-run": "not-run";
|
|
545
|
+
}>>>;
|
|
510
546
|
links: z.ZodNumber;
|
|
511
547
|
tags: z.ZodArray<z.ZodString>;
|
|
512
548
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -597,6 +633,12 @@ export declare const EffectiveEvidenceSchema: z.ZodObject<{
|
|
|
597
633
|
steps: z.ZodNumber;
|
|
598
634
|
annotations: z.ZodNumber;
|
|
599
635
|
attempts: z.ZodNumber;
|
|
636
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
637
|
+
passed: "passed";
|
|
638
|
+
failed: "failed";
|
|
639
|
+
running: "running";
|
|
640
|
+
"not-run": "not-run";
|
|
641
|
+
}>>>;
|
|
600
642
|
links: z.ZodNumber;
|
|
601
643
|
tags: z.ZodArray<z.ZodString>;
|
|
602
644
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -672,6 +714,12 @@ export declare const EffectiveEvidenceSchema: z.ZodObject<{
|
|
|
672
714
|
steps: z.ZodNumber;
|
|
673
715
|
annotations: z.ZodNumber;
|
|
674
716
|
attempts: z.ZodNumber;
|
|
717
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
718
|
+
passed: "passed";
|
|
719
|
+
failed: "failed";
|
|
720
|
+
running: "running";
|
|
721
|
+
"not-run": "not-run";
|
|
722
|
+
}>>>;
|
|
675
723
|
links: z.ZodNumber;
|
|
676
724
|
tags: z.ZodArray<z.ZodString>;
|
|
677
725
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -783,6 +831,12 @@ export declare const EffectiveDeltaSchema: z.ZodObject<{
|
|
|
783
831
|
steps: z.ZodNumber;
|
|
784
832
|
annotations: z.ZodNumber;
|
|
785
833
|
attempts: z.ZodNumber;
|
|
834
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
835
|
+
passed: "passed";
|
|
836
|
+
failed: "failed";
|
|
837
|
+
running: "running";
|
|
838
|
+
"not-run": "not-run";
|
|
839
|
+
}>>>;
|
|
786
840
|
links: z.ZodNumber;
|
|
787
841
|
tags: z.ZodArray<z.ZodString>;
|
|
788
842
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -858,6 +912,12 @@ export declare const EffectiveDeltaSchema: z.ZodObject<{
|
|
|
858
912
|
steps: z.ZodNumber;
|
|
859
913
|
annotations: z.ZodNumber;
|
|
860
914
|
attempts: z.ZodNumber;
|
|
915
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
916
|
+
passed: "passed";
|
|
917
|
+
failed: "failed";
|
|
918
|
+
running: "running";
|
|
919
|
+
"not-run": "not-run";
|
|
920
|
+
}>>>;
|
|
861
921
|
links: z.ZodNumber;
|
|
862
922
|
tags: z.ZodArray<z.ZodString>;
|
|
863
923
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -961,6 +1021,12 @@ export declare const EvidencePageSchema: z.ZodObject<{
|
|
|
961
1021
|
steps: z.ZodNumber;
|
|
962
1022
|
annotations: z.ZodNumber;
|
|
963
1023
|
attempts: z.ZodNumber;
|
|
1024
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
1025
|
+
passed: "passed";
|
|
1026
|
+
failed: "failed";
|
|
1027
|
+
running: "running";
|
|
1028
|
+
"not-run": "not-run";
|
|
1029
|
+
}>>>;
|
|
964
1030
|
links: z.ZodNumber;
|
|
965
1031
|
tags: z.ZodArray<z.ZodString>;
|
|
966
1032
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -1525,11 +1591,18 @@ export declare const TestResultEntrySchema: z.ZodObject<{
|
|
|
1525
1591
|
layer: z.ZodString;
|
|
1526
1592
|
backend: z.ZodString;
|
|
1527
1593
|
detail: z.ZodString;
|
|
1594
|
+
specRevision: z.ZodOptional<z.ZodString>;
|
|
1528
1595
|
evidence: z.ZodOptional<z.ZodObject<{
|
|
1529
1596
|
attachments: z.ZodNumber;
|
|
1530
1597
|
steps: z.ZodNumber;
|
|
1531
1598
|
annotations: z.ZodNumber;
|
|
1532
1599
|
attempts: z.ZodNumber;
|
|
1600
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
1601
|
+
passed: "passed";
|
|
1602
|
+
failed: "failed";
|
|
1603
|
+
running: "running";
|
|
1604
|
+
"not-run": "not-run";
|
|
1605
|
+
}>>>;
|
|
1533
1606
|
links: z.ZodNumber;
|
|
1534
1607
|
tags: z.ZodArray<z.ZodString>;
|
|
1535
1608
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -1622,11 +1695,18 @@ export declare const TestSummarySchema: z.ZodObject<{
|
|
|
1622
1695
|
layer: z.ZodString;
|
|
1623
1696
|
backend: z.ZodString;
|
|
1624
1697
|
detail: z.ZodString;
|
|
1698
|
+
specRevision: z.ZodOptional<z.ZodString>;
|
|
1625
1699
|
evidence: z.ZodOptional<z.ZodObject<{
|
|
1626
1700
|
attachments: z.ZodNumber;
|
|
1627
1701
|
steps: z.ZodNumber;
|
|
1628
1702
|
annotations: z.ZodNumber;
|
|
1629
1703
|
attempts: z.ZodNumber;
|
|
1704
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
1705
|
+
passed: "passed";
|
|
1706
|
+
failed: "failed";
|
|
1707
|
+
running: "running";
|
|
1708
|
+
"not-run": "not-run";
|
|
1709
|
+
}>>>;
|
|
1630
1710
|
links: z.ZodNumber;
|
|
1631
1711
|
tags: z.ZodArray<z.ZodString>;
|
|
1632
1712
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -1914,11 +1994,18 @@ export declare const TestCatalogSchema: z.ZodObject<{
|
|
|
1914
1994
|
layer: z.ZodString;
|
|
1915
1995
|
backend: z.ZodString;
|
|
1916
1996
|
detail: z.ZodString;
|
|
1997
|
+
specRevision: z.ZodOptional<z.ZodString>;
|
|
1917
1998
|
evidence: z.ZodOptional<z.ZodObject<{
|
|
1918
1999
|
attachments: z.ZodNumber;
|
|
1919
2000
|
steps: z.ZodNumber;
|
|
1920
2001
|
annotations: z.ZodNumber;
|
|
1921
2002
|
attempts: z.ZodNumber;
|
|
2003
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2004
|
+
passed: "passed";
|
|
2005
|
+
failed: "failed";
|
|
2006
|
+
running: "running";
|
|
2007
|
+
"not-run": "not-run";
|
|
2008
|
+
}>>>;
|
|
1922
2009
|
links: z.ZodNumber;
|
|
1923
2010
|
tags: z.ZodArray<z.ZodString>;
|
|
1924
2011
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -2133,11 +2220,18 @@ export declare const TestHistorySchema: z.ZodObject<{
|
|
|
2133
2220
|
layer: z.ZodString;
|
|
2134
2221
|
backend: z.ZodString;
|
|
2135
2222
|
detail: z.ZodString;
|
|
2223
|
+
specRevision: z.ZodOptional<z.ZodString>;
|
|
2136
2224
|
evidence: z.ZodOptional<z.ZodObject<{
|
|
2137
2225
|
attachments: z.ZodNumber;
|
|
2138
2226
|
steps: z.ZodNumber;
|
|
2139
2227
|
annotations: z.ZodNumber;
|
|
2140
2228
|
attempts: z.ZodNumber;
|
|
2229
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2230
|
+
passed: "passed";
|
|
2231
|
+
failed: "failed";
|
|
2232
|
+
running: "running";
|
|
2233
|
+
"not-run": "not-run";
|
|
2234
|
+
}>>>;
|
|
2141
2235
|
links: z.ZodNumber;
|
|
2142
2236
|
tags: z.ZodArray<z.ZodString>;
|
|
2143
2237
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -2249,11 +2343,18 @@ export declare const TestHistorySchema: z.ZodObject<{
|
|
|
2249
2343
|
layer: z.ZodString;
|
|
2250
2344
|
backend: z.ZodString;
|
|
2251
2345
|
detail: z.ZodString;
|
|
2346
|
+
specRevision: z.ZodOptional<z.ZodString>;
|
|
2252
2347
|
evidence: z.ZodOptional<z.ZodObject<{
|
|
2253
2348
|
attachments: z.ZodNumber;
|
|
2254
2349
|
steps: z.ZodNumber;
|
|
2255
2350
|
annotations: z.ZodNumber;
|
|
2256
2351
|
attempts: z.ZodNumber;
|
|
2352
|
+
attemptStatuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2353
|
+
passed: "passed";
|
|
2354
|
+
failed: "failed";
|
|
2355
|
+
running: "running";
|
|
2356
|
+
"not-run": "not-run";
|
|
2357
|
+
}>>>;
|
|
2257
2358
|
links: z.ZodNumber;
|
|
2258
2359
|
tags: z.ZodArray<z.ZodString>;
|
|
2259
2360
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -2307,6 +2408,131 @@ export declare const TestHistorySchema: z.ZodObject<{
|
|
|
2307
2408
|
}, z.core.$loose>>>;
|
|
2308
2409
|
}, z.core.$loose>>;
|
|
2309
2410
|
}, z.core.$loose>;
|
|
2411
|
+
/**
|
|
2412
|
+
* `GET /api/reports/tests/reliability`: how reliable one test is inside a scope, and exactly how that figure was counted.
|
|
2413
|
+
* The snapshots one run recorded for one producer, environment and parameter set are one independent execution; only
|
|
2414
|
+
* `passed` and `failed` executions are trials; `notes` say when the sample is too small, pooled, selectively rerun or
|
|
2415
|
+
* bounded. It reads results and never changes a status. It is not a production failure probability.
|
|
2416
|
+
*/
|
|
2417
|
+
export declare const TestReliabilitySchema: z.ZodObject<{
|
|
2418
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
2419
|
+
key: z.ZodString;
|
|
2420
|
+
scope: z.ZodObject<{
|
|
2421
|
+
environment: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2422
|
+
producer: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2423
|
+
parameter: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2424
|
+
branch: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2425
|
+
sha: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2426
|
+
specRevision: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2427
|
+
revision: z.ZodOptional<z.ZodEnum<{
|
|
2428
|
+
any: "any";
|
|
2429
|
+
current: "current";
|
|
2430
|
+
}>>;
|
|
2431
|
+
since: z.ZodOptional<z.ZodNumber>;
|
|
2432
|
+
until: z.ZodOptional<z.ZodNumber>;
|
|
2433
|
+
}, z.core.$loose>;
|
|
2434
|
+
minimumExecutions: z.ZodNumber;
|
|
2435
|
+
sample: z.ZodEnum<{
|
|
2436
|
+
none: "none";
|
|
2437
|
+
insufficient: "insufficient";
|
|
2438
|
+
sufficient: "sufficient";
|
|
2439
|
+
}>;
|
|
2440
|
+
eventual: z.ZodObject<{
|
|
2441
|
+
executions: z.ZodNumber;
|
|
2442
|
+
passed: z.ZodNumber;
|
|
2443
|
+
failed: z.ZodNumber;
|
|
2444
|
+
rate: z.ZodNullable<z.ZodNumber>;
|
|
2445
|
+
}, z.core.$loose>;
|
|
2446
|
+
interval: z.ZodNullable<z.ZodObject<{
|
|
2447
|
+
method: z.ZodLiteral<"wilson">;
|
|
2448
|
+
level: z.ZodNumber;
|
|
2449
|
+
lower: z.ZodNumber;
|
|
2450
|
+
upper: z.ZodNumber;
|
|
2451
|
+
assumptions: z.ZodString;
|
|
2452
|
+
}, z.core.$loose>>;
|
|
2453
|
+
firstAttempt: z.ZodObject<{
|
|
2454
|
+
executions: z.ZodNumber;
|
|
2455
|
+
passed: z.ZodNumber;
|
|
2456
|
+
failed: z.ZodNumber;
|
|
2457
|
+
rate: z.ZodNullable<z.ZodNumber>;
|
|
2458
|
+
}, z.core.$loose>;
|
|
2459
|
+
unrecordedAttempts: z.ZodNumber;
|
|
2460
|
+
attempts: z.ZodObject<{
|
|
2461
|
+
total: z.ZodNumber;
|
|
2462
|
+
retried: z.ZodNumber;
|
|
2463
|
+
recovered: z.ZodNumber;
|
|
2464
|
+
}, z.core.$loose>;
|
|
2465
|
+
currentRevision: z.ZodNullable<z.ZodString>;
|
|
2466
|
+
historical: z.ZodObject<{
|
|
2467
|
+
executions: z.ZodNumber;
|
|
2468
|
+
passed: z.ZodNumber;
|
|
2469
|
+
failed: z.ZodNumber;
|
|
2470
|
+
revisions: z.ZodArray<z.ZodObject<{
|
|
2471
|
+
specRevision: z.ZodString;
|
|
2472
|
+
executions: z.ZodNumber;
|
|
2473
|
+
}, z.core.$loose>>;
|
|
2474
|
+
}, z.core.$loose>;
|
|
2475
|
+
excluded: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
2476
|
+
outsideScope: z.ZodNumber;
|
|
2477
|
+
snapshots: z.ZodNumber;
|
|
2478
|
+
cohorts: z.ZodArray<z.ZodObject<{
|
|
2479
|
+
executions: z.ZodNumber;
|
|
2480
|
+
passed: z.ZodNumber;
|
|
2481
|
+
failed: z.ZodNumber;
|
|
2482
|
+
rate: z.ZodNullable<z.ZodNumber>;
|
|
2483
|
+
environment: z.ZodNullable<z.ZodString>;
|
|
2484
|
+
producer: z.ZodString;
|
|
2485
|
+
parameters: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
2486
|
+
}, z.core.$loose>>;
|
|
2487
|
+
available: z.ZodObject<{
|
|
2488
|
+
environments: z.ZodArray<z.ZodObject<{
|
|
2489
|
+
value: z.ZodString;
|
|
2490
|
+
count: z.ZodNumber;
|
|
2491
|
+
}, z.core.$loose>>;
|
|
2492
|
+
producers: z.ZodArray<z.ZodObject<{
|
|
2493
|
+
value: z.ZodString;
|
|
2494
|
+
count: z.ZodNumber;
|
|
2495
|
+
}, z.core.$loose>>;
|
|
2496
|
+
branches: z.ZodArray<z.ZodObject<{
|
|
2497
|
+
value: z.ZodString;
|
|
2498
|
+
count: z.ZodNumber;
|
|
2499
|
+
}, z.core.$loose>>;
|
|
2500
|
+
specRevisions: z.ZodArray<z.ZodObject<{
|
|
2501
|
+
value: z.ZodString;
|
|
2502
|
+
count: z.ZodNumber;
|
|
2503
|
+
}, z.core.$loose>>;
|
|
2504
|
+
}, z.core.$loose>;
|
|
2505
|
+
notes: z.ZodArray<z.ZodObject<{
|
|
2506
|
+
code: z.ZodString;
|
|
2507
|
+
severity: z.ZodEnum<{
|
|
2508
|
+
info: "info";
|
|
2509
|
+
warning: "warning";
|
|
2510
|
+
}>;
|
|
2511
|
+
message: z.ZodString;
|
|
2512
|
+
}, z.core.$loose>>;
|
|
2513
|
+
executions: z.ZodArray<z.ZodObject<{
|
|
2514
|
+
run: z.ZodString;
|
|
2515
|
+
at: z.ZodNumber;
|
|
2516
|
+
status: z.ZodString;
|
|
2517
|
+
counted: z.ZodBoolean;
|
|
2518
|
+
excluded: z.ZodOptional<z.ZodString>;
|
|
2519
|
+
environment: z.ZodNullable<z.ZodString>;
|
|
2520
|
+
producer: z.ZodString;
|
|
2521
|
+
kind: z.ZodString;
|
|
2522
|
+
parameters: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
2523
|
+
branch: z.ZodNullable<z.ZodString>;
|
|
2524
|
+
sha: z.ZodNullable<z.ZodString>;
|
|
2525
|
+
runUrl: z.ZodNullable<z.ZodString>;
|
|
2526
|
+
layer: z.ZodString;
|
|
2527
|
+
backend: z.ZodString;
|
|
2528
|
+
durationMs: z.ZodNullable<z.ZodNumber>;
|
|
2529
|
+
specRevision: z.ZodOptional<z.ZodString>;
|
|
2530
|
+
snapshots: z.ZodNumber;
|
|
2531
|
+
attempts: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2532
|
+
firstAttempt: z.ZodOptional<z.ZodString>;
|
|
2533
|
+
republished: z.ZodBoolean;
|
|
2534
|
+
}, z.core.$loose>>;
|
|
2535
|
+
}, z.core.$loose>;
|
|
2310
2536
|
/** A run: the layers that name the same execution (else share a run URL, else a branch and commit), with what they recorded. */
|
|
2311
2537
|
export declare const ReportRunSchema: z.ZodObject<{
|
|
2312
2538
|
key: z.ZodString;
|
package/dist/schema/src/api.js
CHANGED
|
@@ -85,6 +85,7 @@ export const EvidenceSummarySchema = z.looseObject({
|
|
|
85
85
|
steps: z.number().int().nonnegative(),
|
|
86
86
|
annotations: z.number().int().nonnegative(),
|
|
87
87
|
attempts: z.number().int().nonnegative(),
|
|
88
|
+
attemptStatuses: z.array(EvidenceStatusSchema).optional().describe('The status of each recorded try, in the order they were made. Absent when no try was recorded, and in reports written before this was recorded: a first try is then unknown, never assumed to have passed'),
|
|
88
89
|
links: z.number().int().nonnegative(),
|
|
89
90
|
tags: z.array(z.string()),
|
|
90
91
|
artifactTags: z.array(z.string()).optional().describe('Normalized tags of the attachments themselves, sorted and distinct. Absent when no attachment is tagged; never inherited from a check or run'),
|
|
@@ -270,6 +271,7 @@ export const TestResultEntrySchema = z.looseObject({
|
|
|
270
271
|
layer: z.string().describe('The id of the layer that recorded it'),
|
|
271
272
|
backend: z.string(),
|
|
272
273
|
detail: z.string().describe('Why it has its status, at most 500 characters'),
|
|
274
|
+
specRevision: z.string().optional().describe('The fingerprint of its spec text that the layer recorded, when it recorded one. Two results with different revisions were recorded against different promises. Absent: not recorded, never assumed to match'),
|
|
273
275
|
evidence: EvidenceSummarySchema.optional(),
|
|
274
276
|
latency: z.array(MeasurementSchema).optional().describe('Its product-latency measurements (`kind: product-latency`), when it recorded any. Separate from `durationMs`, which is how long the test took')
|
|
275
277
|
});
|
|
@@ -390,6 +392,55 @@ export const TestHistorySchema = z.looseObject({
|
|
|
390
392
|
test: TestSummarySchema,
|
|
391
393
|
history: z.array(TestResultEntrySchema)
|
|
392
394
|
});
|
|
395
|
+
const ReliabilityRateSchema = z.looseObject({
|
|
396
|
+
executions: z.number().int().nonnegative().describe('Independent executions that passed or failed'),
|
|
397
|
+
passed: z.number().int().nonnegative(),
|
|
398
|
+
failed: z.number().int().nonnegative(),
|
|
399
|
+
rate: z.number().nullable().describe('passed / executions, or null with none')
|
|
400
|
+
});
|
|
401
|
+
/**
|
|
402
|
+
* `GET /api/reports/tests/reliability`: how reliable one test is inside a scope, and exactly how that figure was counted.
|
|
403
|
+
* The snapshots one run recorded for one producer, environment and parameter set are one independent execution; only
|
|
404
|
+
* `passed` and `failed` executions are trials; `notes` say when the sample is too small, pooled, selectively rerun or
|
|
405
|
+
* bounded. It reads results and never changes a status. It is not a production failure probability.
|
|
406
|
+
*/
|
|
407
|
+
export const TestReliabilitySchema = z.looseObject({
|
|
408
|
+
schemaVersion: z.literal(1),
|
|
409
|
+
key: z.string().describe('The test\'s key'),
|
|
410
|
+
scope: z.looseObject({
|
|
411
|
+
environment: z.array(z.string()).optional(), producer: z.array(z.string()).optional(), parameter: z.array(z.string()).optional(),
|
|
412
|
+
branch: z.array(z.string()).optional(), sha: z.array(z.string()).optional(), specRevision: z.array(z.string()).optional(),
|
|
413
|
+
revision: z.enum(['current', 'any']).optional(), since: z.number().optional(), until: z.number().optional()
|
|
414
|
+
}).describe('What was asked: the selection the figures are about'),
|
|
415
|
+
minimumExecutions: z.number().int().positive().describe('Completed executions below which the sample is `insufficient`'),
|
|
416
|
+
sample: z.enum(['none', 'insufficient', 'sufficient']).describe('A count only: it says nothing about whether the executions are representative; read `notes`'),
|
|
417
|
+
eventual: ReliabilityRateSchema.describe('Executions that passed in the end, over those that passed or failed'),
|
|
418
|
+
interval: z.looseObject({ method: z.literal('wilson'), level: z.number(), lower: z.number(), upper: z.number(), assumptions: z.string() }).nullable().describe('An interval estimate with the assumptions it needs; null without an execution'),
|
|
419
|
+
firstAttempt: ReliabilityRateSchema.describe('Over the executions that recorded their tries: those whose first try passed'),
|
|
420
|
+
unrecordedAttempts: z.number().int().nonnegative().describe('Counted executions that recorded no tries: their first try is unknown, never assumed to have passed'),
|
|
421
|
+
attempts: z.looseObject({ total: z.number().int().nonnegative(), retried: z.number().int().nonnegative(), recovered: z.number().int().nonnegative() }),
|
|
422
|
+
currentRevision: z.string().nullable().describe('The spec revision `revision=current` counted, or null'),
|
|
423
|
+
historical: z.looseObject({
|
|
424
|
+
executions: z.number().int().nonnegative(), passed: z.number().int().nonnegative(), failed: z.number().int().nonnegative(),
|
|
425
|
+
revisions: z.array(z.looseObject({ specRevision: z.string(), executions: z.number().int().nonnegative() }))
|
|
426
|
+
}).describe('Earlier spec revisions: context only, counted nowhere above'),
|
|
427
|
+
excluded: z.record(z.string(), z.number().int().nonnegative()).describe('Executions in the scope that are not trials, by reason: `not-run`, `unfinished`, `unknown-status`, `historical-revision`, `revision-not-recorded`'),
|
|
428
|
+
outsideScope: z.number().int().nonnegative().describe('Executions the scope did not select'),
|
|
429
|
+
snapshots: z.number().int().nonnegative().describe('Raw recorded snapshots behind the counted executions'),
|
|
430
|
+
cohorts: z.array(ReliabilityRateSchema.extend({ environment: z.string().nullable(), producer: z.string(), parameters: z.record(z.string(), z.string()) })),
|
|
431
|
+
available: z.looseObject({
|
|
432
|
+
environments: z.array(FacetValueSchema), producers: z.array(FacetValueSchema), branches: z.array(FacetValueSchema), specRevisions: z.array(FacetValueSchema)
|
|
433
|
+
}).describe('What a scope could choose among, with independent executions'),
|
|
434
|
+
notes: z.array(z.looseObject({ code: z.string().describe('An open set: treat a code you do not know as informational'), severity: z.enum(['warning', 'info']), message: z.string() })),
|
|
435
|
+
executions: z.array(z.looseObject({
|
|
436
|
+
run: z.string(), at: z.number(), status: z.string(), counted: z.boolean(), excluded: z.string().optional(),
|
|
437
|
+
environment: z.string().nullable(), producer: z.string(), kind: z.string(), parameters: z.record(z.string(), z.string()),
|
|
438
|
+
branch: z.string().nullable(), sha: z.string().nullable(), runUrl: z.string().nullable(), layer: z.string(), backend: z.string(),
|
|
439
|
+
durationMs: z.number().nullable(), specRevision: z.string().optional(), snapshots: z.number().int().positive(),
|
|
440
|
+
attempts: z.array(z.string()).optional().describe('The status of each recorded try, in order'), firstAttempt: z.string().optional(),
|
|
441
|
+
republished: z.boolean().describe('A failed snapshot of this execution was followed by a later one')
|
|
442
|
+
})).describe('Every independent execution of the selection, newest first: the denominator, open to inspection')
|
|
443
|
+
});
|
|
393
444
|
/** A run: the layers that name the same execution (else share a run URL, else a branch and commit), with what they recorded. */
|
|
394
445
|
export const ReportRunSchema = z.looseObject({
|
|
395
446
|
key: z.string().describe('`run:<id>` for an execution a producer named, else the run URL, else `branch@sha`. Pass it to `/api/reports/runs/detail?key=` or `/api/reports/tests?run=`'),
|
package/dist/server/src/app.js
CHANGED
|
@@ -28,6 +28,7 @@ import { listRunSummaries, readRunFile } from '../../reports/src/run-bundle.js';
|
|
|
28
28
|
import { latestSpecSet, readSpecBody } from '../../reports/src/spec-set.js';
|
|
29
29
|
import { catalogHealth, healthMarkdown, parseRootMappings } from '../../reports/src/catalog-health.js';
|
|
30
30
|
import { parseArtifactFilter } from '../../reports/src/artifact-query.js';
|
|
31
|
+
import { parseReliabilityScope, reliability, reliabilityMarkdown } from '../../reports/src/reliability.js';
|
|
31
32
|
import { artifactList, artifactsMarkdown, catalogMarkdown, catalogModel, historyMarkdown, parseTestQuery, runDetail, runList, runMarkdown, runsMarkdown, testCatalog, testHistory } from '../../reports/src/test-catalog.js';
|
|
32
33
|
import { llmsTxt } from './llms.js';
|
|
33
34
|
import { openApiDocument } from './openapi.js';
|
|
@@ -467,6 +468,20 @@ function createProjectApplication(options) {
|
|
|
467
468
|
return problemResponse(404, 'No test in the report has that key.');
|
|
468
469
|
return answer(c, found.version, () => document, () => historyMarkdown(document), `history|${key}|${wantsMarkdown(c)}`);
|
|
469
470
|
});
|
|
471
|
+
app.get('/api/reports/tests/reliability', async (c) => {
|
|
472
|
+
if (!index.ready)
|
|
473
|
+
return notReady(c);
|
|
474
|
+
const key = c.req.query('key');
|
|
475
|
+
if (!key)
|
|
476
|
+
return problemResponse(400, 'Name the test with ?key=, a key from GET /api/reports/tests.');
|
|
477
|
+
const found = await catalog();
|
|
478
|
+
const recorded = testHistory(found, key);
|
|
479
|
+
if (!recorded)
|
|
480
|
+
return problemResponse(404, 'No test in the report has that key.');
|
|
481
|
+
const search = new URL(c.req.url).searchParams;
|
|
482
|
+
const document = () => reliability(key, recorded.history, parseReliabilityScope(search));
|
|
483
|
+
return answer(c, found.version, document, () => reliabilityMarkdown(document()), `reliability|${search.toString()}|${wantsMarkdown(c)}`);
|
|
484
|
+
});
|
|
470
485
|
app.get('/api/reports/runs', async (c) => {
|
|
471
486
|
if (!index.ready)
|
|
472
487
|
return notReady(c);
|
package/dist/server/src/llms.js
CHANGED
|
@@ -68,6 +68,7 @@ Every endpoint below answers JSON, or Markdown with \`format=markdown\`. Prefix
|
|
|
68
68
|
curl "${url}/api/projects/$ATLAS_PROJECT/reports/tests?format=markdown&limit=50" # summary, environments, domains, failing, flaky, slowest, then the tests
|
|
69
69
|
curl "${url}/api/projects/$ATLAS_PROJECT/reports/tests?status=failed,flaky&environment=desktop-web" # filter: q, status, environment, producer, domain, spec, tag, run; sort, offset, limit
|
|
70
70
|
curl "${url}/api/projects/$ATLAS_PROJECT/reports/tests/history?key=<url-encoded test key>" # one test: every recorded result, durations, branches, CI runs
|
|
71
|
+
curl "${url}/api/projects/$ATLAS_PROJECT/reports/tests/reliability?key=<url-encoded test key>&environment=phone&format=markdown" # how reliable one test is in a scope: independent executions, first-try vs eventual success, what was excluded and why
|
|
71
72
|
curl "${url}/api/projects/$ATLAS_PROJECT/reports/tests/health?format=markdown" # why Specs, domains and counts disagree; add root=<from>><to> to declare a path-root mapping
|
|
72
73
|
curl "${url}/api/projects/$ATLAS_PROJECT/reports/runs?format=markdown" # CI runs, newest first, with their results by status and video counts
|
|
73
74
|
curl "${url}/api/projects/$ATLAS_PROJECT/reports/runs?video=true&format=markdown" # only runs with a playable video recording
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { z } from 'zod/v4';
|
|
16
16
|
import { ProjectsSchema } from '../../schema/src/project.js';
|
|
17
|
-
import { EffectiveDeltaSchema, EffectiveEvidenceSchema, EvidencePageSchema, HealthSchema, LayerRowsSchema, CheckDetailSchema, OutlineSchema, ProblemSchema, ReadySchema, ServerInfoSchema, StoreListingSchema, StoreWriteResultSchema, ChecksResultSchema, HelloEventSchema, ReportEventSchema, PingEventSchema, TestCatalogSchema, CatalogHealthSchema, TestHistorySchema, RunListSchema, RunDetailSchema, ArtifactListSchema, ArtifactTagEditSchema, ArtifactTagEntrySchema, ArtifactTagsSchema } from '../../schema/src/api.js';
|
|
17
|
+
import { EffectiveDeltaSchema, EffectiveEvidenceSchema, EvidencePageSchema, HealthSchema, LayerRowsSchema, CheckDetailSchema, OutlineSchema, ProblemSchema, ReadySchema, ServerInfoSchema, StoreListingSchema, StoreWriteResultSchema, ChecksResultSchema, HelloEventSchema, ReportEventSchema, PingEventSchema, TestCatalogSchema, CatalogHealthSchema, TestHistorySchema, TestReliabilitySchema, RunListSchema, RunDetailSchema, ArtifactListSchema, ArtifactTagEditSchema, ArtifactTagEntrySchema, ArtifactTagsSchema } from '../../schema/src/api.js';
|
|
18
18
|
import { LiveRunSchema, LiveRunStartSchema, LiveRunUpdateSchema, ServerEditableSettingsSchema, ServerSettingsSnapshotSchema, GcPolicySchema, GcSnapshotSchema, GcRunResultSchema, AtlasChangeSchema, PublishChecksSchema, ReportSourcesSchema, ReportStatusSchema, RunsIndexSchema, SpecIndexSchema } from '../../schema/src/index.js';
|
|
19
19
|
/** The version of the API described, `major.minor.patch`: the minor grows when an operation or field is added, the major never within `/api`. */
|
|
20
20
|
export const API_VERSION = '1.5.0';
|
|
@@ -37,7 +37,7 @@ const COMPONENTS = {
|
|
|
37
37
|
StoreListing: [StoreListingSchema, 'output'], StoreWriteResult: [StoreWriteResultSchema, 'output'],
|
|
38
38
|
Outline: [OutlineSchema, 'output'], EvidencePage: [EvidencePageSchema, 'output'], LayerRows: [LayerRowsSchema, 'output'], CheckDetail: [CheckDetailSchema, 'output'],
|
|
39
39
|
ArtifactTagEdit: [ArtifactTagEditSchema, 'input'], ArtifactTagEntry: [ArtifactTagEntrySchema, 'output'], ArtifactTags: [ArtifactTagsSchema, 'output'],
|
|
40
|
-
TestCatalog: [TestCatalogSchema, 'output'], CatalogHealth: [CatalogHealthSchema, 'output'], TestHistory: [TestHistorySchema, 'output'], RunList: [RunListSchema, 'output'], ArtifactList: [ArtifactListSchema, 'output'], RunDetail: [RunDetailSchema, 'output'],
|
|
40
|
+
TestCatalog: [TestCatalogSchema, 'output'], CatalogHealth: [CatalogHealthSchema, 'output'], TestHistory: [TestHistorySchema, 'output'], TestReliability: [TestReliabilitySchema, 'output'], RunList: [RunListSchema, 'output'], ArtifactList: [ArtifactListSchema, 'output'], RunDetail: [RunDetailSchema, 'output'],
|
|
41
41
|
SpecIndex: [SpecIndexSchema, 'output'], ReportSources: [ReportSourcesSchema, 'output'], RunsIndex: [RunsIndexSchema, 'output'],
|
|
42
42
|
RunEvent: [LiveRunSchema, 'output'], HelloEvent: [HelloEventSchema, 'output'], ReportEvent: [ReportEventSchema, 'output'], AtlasChangeEvent: [AtlasChangeSchema, 'output'], PingEvent: [PingEventSchema, 'output']
|
|
43
43
|
};
|
|
@@ -328,6 +328,29 @@ const BASE_OPERATIONS = [
|
|
|
328
328
|
],
|
|
329
329
|
responses: { '200': json('The test and its history.', 'TestHistory'), '304': { description: 'Unchanged since the `If-None-Match` ETag.' }, '400': problem('No `key`.'), '401': UNAUTHORIZED, '404': problem('No test in the report has that key.'), '503': NOT_READY }
|
|
330
330
|
},
|
|
331
|
+
{
|
|
332
|
+
route: 'GET /api/reports/tests/reliability', path: '/api/reports/tests/reliability', operationId: 'getTestReliability', tag: 'Report', role: 'read',
|
|
333
|
+
summary: 'How reliable one test is in a scope, and how that was counted',
|
|
334
|
+
description: [
|
|
335
|
+
'A success rate for one test that says what it counted. The snapshots one run recorded for one producer, environment and parameter set (running, finished, enriched) are one independent execution; its last word counts once with the tries it recorded. `eventual` is the share of executions that passed in the end, `firstAttempt` the share whose first try passed (over executions that recorded their tries; the rest are `unrecordedAttempts`, never assumed to have passed first time).',
|
|
336
|
+
'',
|
|
337
|
+
'Choose the scope with `environment`, `producer`, `parameter` (`key=value`), `branch`, `sha`, `specRevision`, `since` and `until`; executions elsewhere never count. By default only the newest recorded spec revision counts and earlier ones appear under `historical`; send `revision=any` to pool them. Only `passed` and `failed` executions are trials: `not-run` and unfinished ones are listed under `excluded` and never counted as a pass. `sample` is `none`, `insufficient` (fewer than `minimumExecutions`) or `sufficient`, a count only: `notes` say when environments, producers or branches are pooled, failed cases were published again, or history is bounded to the newest 100 results. `executions` is the denominator, open to inspection. The interval states its assumptions. This is not a production failure probability. Send `format=markdown` for Markdown.'
|
|
338
|
+
].join('\n'),
|
|
339
|
+
parameters: [
|
|
340
|
+
{ name: 'key', in: 'query', required: true, description: 'The test\'s `key` from `/api/reports/tests`.', schema: str, example: '["specs/checkout/pay.feature","Pay with a card"]' },
|
|
341
|
+
{ name: 'environment', in: 'query', description: 'Environments or devices to count. Comma-separated.', schema: str, example: 'phone' },
|
|
342
|
+
{ name: 'producer', in: 'query', description: 'Producers to count. Comma-separated.', schema: str },
|
|
343
|
+
{ name: 'parameter', in: 'query', description: 'Parameter choices `key=value`; all must match. Comma-separated.', schema: str, example: 'device=small' },
|
|
344
|
+
{ name: 'branch', in: 'query', description: 'Branches to count. Comma-separated.', schema: str },
|
|
345
|
+
{ name: 'sha', in: 'query', description: 'Commits: a full id or a prefix of at least seven characters. Comma-separated.', schema: str },
|
|
346
|
+
{ name: 'specRevision', in: 'query', description: 'Only executions recorded against these spec fingerprints (overrides `revision`). Comma-separated.', schema: str },
|
|
347
|
+
{ name: 'revision', in: 'query', description: '`any` pools every spec revision; otherwise only the newest recorded one counts.', schema: { type: 'string', enum: ['current', 'any'] } },
|
|
348
|
+
{ name: 'since', in: 'query', description: 'Only executions at or after this time: epoch milliseconds or a date.', schema: str, example: '2026-01-01' },
|
|
349
|
+
{ name: 'until', in: 'query', description: 'Only executions at or before this time: epoch milliseconds or a date.', schema: str },
|
|
350
|
+
{ name: 'format', in: 'query', description: '`markdown` for Markdown instead of JSON.', schema: { type: 'string', enum: ['json', 'markdown'] } }
|
|
351
|
+
],
|
|
352
|
+
responses: { '200': json('The reliability of the test in the scope.', 'TestReliability'), '304': { description: 'Unchanged since the `If-None-Match` ETag.' }, '400': problem('No `key`.'), '401': UNAUTHORIZED, '404': problem('No test in the report has that key.'), '503': NOT_READY }
|
|
353
|
+
},
|
|
331
354
|
{
|
|
332
355
|
route: 'GET /api/reports/artifact-tags', path: '/api/reports/artifact-tags', operationId: 'getArtifactTags', tag: 'Report', role: 'read',
|
|
333
356
|
summary: 'Reviewer tags of attachments: every recorded edit',
|
|
@@ -598,6 +598,54 @@ Scoped to one project. The same project may be selected on the unprefixed API us
|
|
|
598
598
|
|
|
599
599
|
Responses: `200` The test and its history.; `304` Unchanged since the `If-None-Match` ETag.; `400` No `key`.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.; `404` No test in the report has that key.; `503` The server is still reading its backends. Retry after the number of seconds in `Retry-After`.
|
|
600
600
|
|
|
601
|
+
### How reliable one test is in a scope, and how that was counted
|
|
602
|
+
|
|
603
|
+
`GET /api/reports/tests/reliability` · role: read
|
|
604
|
+
|
|
605
|
+
A success rate for one test that says what it counted. The snapshots one run recorded for one producer, environment and parameter set (running, finished, enriched) are one independent execution; its last word counts once with the tries it recorded. `eventual` is the share of executions that passed in the end, `firstAttempt` the share whose first try passed (over executions that recorded their tries; the rest are `unrecordedAttempts`, never assumed to have passed first time).
|
|
606
|
+
|
|
607
|
+
Choose the scope with `environment`, `producer`, `parameter` (`key=value`), `branch`, `sha`, `specRevision`, `since` and `until`; executions elsewhere never count. By default only the newest recorded spec revision counts and earlier ones appear under `historical`; send `revision=any` to pool them. Only `passed` and `failed` executions are trials: `not-run` and unfinished ones are listed under `excluded` and never counted as a pass. `sample` is `none`, `insufficient` (fewer than `minimumExecutions`) or `sufficient`, a count only: `notes` say when environments, producers or branches are pooled, failed cases were published again, or history is bounded to the newest 100 results. `executions` is the denominator, open to inspection. The interval states its assumptions. This is not a production failure probability. Send `format=markdown` for Markdown.
|
|
608
|
+
|
|
609
|
+
- `key` (query, required): The test's `key` from `/api/reports/tests`.
|
|
610
|
+
- `environment` (query): Environments or devices to count. Comma-separated.
|
|
611
|
+
- `producer` (query): Producers to count. Comma-separated.
|
|
612
|
+
- `parameter` (query): Parameter choices `key=value`; all must match. Comma-separated.
|
|
613
|
+
- `branch` (query): Branches to count. Comma-separated.
|
|
614
|
+
- `sha` (query): Commits: a full id or a prefix of at least seven characters. Comma-separated.
|
|
615
|
+
- `specRevision` (query): Only executions recorded against these spec fingerprints (overrides `revision`). Comma-separated.
|
|
616
|
+
- `revision` (query): `any` pools every spec revision; otherwise only the newest recorded one counts.
|
|
617
|
+
- `since` (query): Only executions at or after this time: epoch milliseconds or a date.
|
|
618
|
+
- `until` (query): Only executions at or before this time: epoch milliseconds or a date.
|
|
619
|
+
- `format` (query): `markdown` for Markdown instead of JSON.
|
|
620
|
+
- `project` (query): Project slug. Alternatively send X-Atlas-Project or use the project-prefixed route. Omit for the default project. Conflicting selectors are refused.
|
|
621
|
+
|
|
622
|
+
Responses: `200` The reliability of the test in the scope.; `304` Unchanged since the `If-None-Match` ETag.; `400` No `key`.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.; `404` No test in the report has that key.; `503` The server is still reading its backends. Retry after the number of seconds in `Retry-After`.
|
|
623
|
+
|
|
624
|
+
### How reliable one test is in a scope, and how that was counted
|
|
625
|
+
|
|
626
|
+
`GET /api/projects/{project}/reports/tests/reliability` · role: read
|
|
627
|
+
|
|
628
|
+
A success rate for one test that says what it counted. The snapshots one run recorded for one producer, environment and parameter set (running, finished, enriched) are one independent execution; its last word counts once with the tries it recorded. `eventual` is the share of executions that passed in the end, `firstAttempt` the share whose first try passed (over executions that recorded their tries; the rest are `unrecordedAttempts`, never assumed to have passed first time).
|
|
629
|
+
|
|
630
|
+
Choose the scope with `environment`, `producer`, `parameter` (`key=value`), `branch`, `sha`, `specRevision`, `since` and `until`; executions elsewhere never count. By default only the newest recorded spec revision counts and earlier ones appear under `historical`; send `revision=any` to pool them. Only `passed` and `failed` executions are trials: `not-run` and unfinished ones are listed under `excluded` and never counted as a pass. `sample` is `none`, `insufficient` (fewer than `minimumExecutions`) or `sufficient`, a count only: `notes` say when environments, producers or branches are pooled, failed cases were published again, or history is bounded to the newest 100 results. `executions` is the denominator, open to inspection. The interval states its assumptions. This is not a production failure probability. Send `format=markdown` for Markdown.
|
|
631
|
+
|
|
632
|
+
Scoped to one project. The same project may be selected on the unprefixed API using ?project= or X-Atlas-Project. Unknown projects return 404 on reads and are created by an authenticated upload.
|
|
633
|
+
|
|
634
|
+
- `project` (path, required): Project slug. Alternatively send X-Atlas-Project or use the project-prefixed route. Omit for the default project. Conflicting selectors are refused.
|
|
635
|
+
- `key` (query, required): The test's `key` from `/api/reports/tests`.
|
|
636
|
+
- `environment` (query): Environments or devices to count. Comma-separated.
|
|
637
|
+
- `producer` (query): Producers to count. Comma-separated.
|
|
638
|
+
- `parameter` (query): Parameter choices `key=value`; all must match. Comma-separated.
|
|
639
|
+
- `branch` (query): Branches to count. Comma-separated.
|
|
640
|
+
- `sha` (query): Commits: a full id or a prefix of at least seven characters. Comma-separated.
|
|
641
|
+
- `specRevision` (query): Only executions recorded against these spec fingerprints (overrides `revision`). Comma-separated.
|
|
642
|
+
- `revision` (query): `any` pools every spec revision; otherwise only the newest recorded one counts.
|
|
643
|
+
- `since` (query): Only executions at or after this time: epoch milliseconds or a date.
|
|
644
|
+
- `until` (query): Only executions at or before this time: epoch milliseconds or a date.
|
|
645
|
+
- `format` (query): `markdown` for Markdown instead of JSON.
|
|
646
|
+
|
|
647
|
+
Responses: `200` The reliability of the test in the scope.; `304` Unchanged since the `If-None-Match` ETag.; `400` No `key`.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.; `404` No test in the report has that key.; `503` The server is still reading its backends. Retry after the number of seconds in `Retry-After`.
|
|
648
|
+
|
|
601
649
|
### Reviewer tags of attachments: every recorded edit
|
|
602
650
|
|
|
603
651
|
`GET /api/reports/artifact-tags` · role: read
|