@crvouga/atlas 1.17.0 → 1.18.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/artifact-query.d.ts +14 -2
- package/dist/reports/src/artifact-query.js +13 -4
- package/dist/reports/src/evidence-detail.js +7 -4
- package/dist/reports/src/evidence-types.d.ts +4 -0
- package/dist/reports/src/recording-receipt.d.ts +23 -0
- package/dist/reports/src/recording-receipt.js +16 -0
- package/dist/reports/src/recording-verify.d.ts +74 -0
- package/dist/reports/src/recording-verify.js +142 -0
- package/dist/reports/src/report-cli.d.ts +2 -2
- package/dist/reports/src/report-cli.js +53 -3
- package/dist/reports/src/test-catalog.d.ts +7 -1
- package/dist/reports/src/test-catalog.js +10 -4
- package/dist/schema/src/api.d.ts +84 -0
- package/dist/schema/src/api.js +11 -2
- package/dist/schema/src/cli-results.d.ts +51 -1
- package/dist/schema/src/cli-results.js +25 -1
- package/dist/server/src/openapi.js +1 -0
- package/docs/agents.md +1 -0
- package/docs/reference/cli.md +11 -2
- package/docs/reference/http-api.md +2 -0
- package/docs/reference/reports.md +185 -9
- package/docs/reference/schema.md +19 -1
- package/docs/rich-evidence.md +32 -5
- package/docs/server.md +1 -1
- package/llms-full.txt +47 -8
- package/package.json +1 -1
- package/packages/schema/schemas/effective-delta.schema.json +8 -0
- package/packages/schema/schemas/effective-evidence.schema.json +8 -0
- package/packages/schema/schemas/evidence-page.schema.json +4 -0
- package/packages/schema/schemas/layer-rows.schema.json +4 -0
- package/packages/schema/schemas/report-run.schema.json +74 -0
- package/packages/schema/schemas/report-runs.schema.json +86 -0
- package/packages/schema/schemas/review-collection.schema.json +4 -0
- package/packages/schema/schemas/review-manifest.schema.json +4 -0
- package/packages/schema/schemas/test-catalog.schema.json +4 -0
- package/packages/schema/schemas/test-history.schema.json +8 -0
- package/packages/schema/schemas/verify-recordings-result.schema.json +97 -0
- package/packages/server/openapi.json +252 -0
- package/packages/visualizer/src/explorer/ArtifactsView.tsx +3 -2
- package/packages/visualizer/src/explorer/RunsView.tsx +28 -3
- package/packages/visualizer/src/explorer/filters.tsx +11 -3
- package/packages/visualizer/src/explorer/search.ts +6 -2
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
* @see docs/server.md#reading-the-report-as-an-agent
|
|
24
24
|
*/
|
|
25
25
|
import { displayTag, normalizeTag, normalizeTags } from './artifact-tags.js';
|
|
26
|
-
import { facetsOf, forRuns, labelList, matchesFilter, outcomeOfCounts, splitList, usedFilters } from './artifact-query.js';
|
|
26
|
+
import { facetsOf, forArtifacts, forRuns, labelList, matchesFilter, outcomeOfCounts, splitList, usedFilters } from './artifact-query.js';
|
|
27
|
+
import { runRecordings } from './recording-receipt.js';
|
|
27
28
|
import { videoCounts } from './evidence-detail.js';
|
|
28
29
|
import { productLatency } from './latency.js';
|
|
29
30
|
import { matchesScope, scopeTokens, UNKNOWN_SCOPE } from './evidence-scope.js';
|
|
@@ -148,7 +149,7 @@ export class TestHistory {
|
|
|
148
149
|
const key = runKey(layer);
|
|
149
150
|
let run = this.#runs.get(key);
|
|
150
151
|
if (!run) {
|
|
151
|
-
run = { key, runUrl: layer.runUrl, branch: layer.branch, sha: layer.sha, start: layer.recordedAtMs, end: layer.recordedAtMs, firstAt: layer.recordedAtMs, first: layer.id, producers: new Set(), environments: new Set(), layers: 0, runId: layer.run?.id, title: undefined, titledAt: 0, titledBy: '', freshness: undefined, videos: [], attachments: 0, members: [], evidence: { tags: new Set(), artifactTags: new Set(), roles: new Set(), labels: new Set() } };
|
|
152
|
+
run = { key, runUrl: layer.runUrl, branch: layer.branch, sha: layer.sha, start: layer.recordedAtMs, end: layer.recordedAtMs, firstAt: layer.recordedAtMs, first: layer.id, producers: new Set(), environments: new Set(), layers: 0, runId: layer.run?.id, title: undefined, titledAt: 0, titledBy: '', freshness: undefined, videos: [], receipts: [], attachments: 0, members: [], evidence: { tags: new Set(), artifactTags: new Set(), roles: new Set(), labels: new Set() } };
|
|
152
153
|
this.#runs.set(key, run);
|
|
153
154
|
}
|
|
154
155
|
// A run is told by its first layer (by time, then id), whatever order its layers arrive in.
|
|
@@ -177,6 +178,7 @@ export class TestHistory {
|
|
|
177
178
|
run.layers += 1;
|
|
178
179
|
if (layer.evidence?.videos)
|
|
179
180
|
run.videos.push(...layer.evidence.videos);
|
|
181
|
+
run.receipts.push(layer.recordings);
|
|
180
182
|
const held = layer.evidence?.attachments ?? 0;
|
|
181
183
|
run.attachments += held;
|
|
182
184
|
const layerVideos = videoCounts(layer.evidence?.videos);
|
|
@@ -376,6 +378,7 @@ function runSummary(run, cells) {
|
|
|
376
378
|
}
|
|
377
379
|
failed.sort((a, b) => compareText(a.i.slot, b.i.slot) || compareText(a.r.o.place, b.r.o.place) || compareText(a.r.k, b.r.k));
|
|
378
380
|
const video = videoCounts(videos);
|
|
381
|
+
const recordings = runRecordings(run.receipts);
|
|
379
382
|
const failing = failed.slice(0, 20).map(cell => ({ key: cell.i.slot, title: cell.i.title, environment: cell.r.o.environment, detail: (cell.r.t.split('\n')[0] ?? '').slice(0, 500) }));
|
|
380
383
|
return {
|
|
381
384
|
key: run.key, ...(run.runId ? { runId: run.runId } : {}), ...(run.title ? { title: run.title } : {}), ...(run.freshness ? { freshness: run.freshness } : {}),
|
|
@@ -384,6 +387,7 @@ function runSummary(run, cells) {
|
|
|
384
387
|
producers: [...run.producers].sort(), environments: [...run.environments].sort(),
|
|
385
388
|
layers: run.layers, tests: tests.size, counts, totalDurationMs: measured ? total : null, failing,
|
|
386
389
|
...(video ? { videos: video } : {}),
|
|
390
|
+
...(recordings ? { recordings } : {}),
|
|
387
391
|
...(run.attachments ? { attachments: run.attachments } : {}),
|
|
388
392
|
...(carried.artifactTags.size ? { artifactTags: [...carried.artifactTags].sort() } : {}),
|
|
389
393
|
...(carried.roles.size ? { types: typesOf(carried.roles, (video?.recordings ?? 0) > 0) } : {}),
|
|
@@ -737,7 +741,7 @@ export function fieldsOfRun(run) {
|
|
|
737
741
|
text: [run.title ?? '', run.key, run.branch ?? '', run.sha ?? '', ...run.producers, ...run.environments, ...artifactTags, ...(run.tags ?? []), ...labels].join('\n').toLowerCase(),
|
|
738
742
|
artifactTags, tags: [...new Set([...(run.tags ?? []), ...artifactTags])], types, media: types.map(type => ({ type, tags: artifactTags })), labels,
|
|
739
743
|
environments: run.environments, producers: run.producers, branches: run.branch ? [run.branch] : [], shas: run.sha ? [run.sha.toLowerCase()] : [],
|
|
740
|
-
outcomes: [outcomeOfCounts(run.counts)], at: run.endedAtMs,
|
|
744
|
+
outcomes: [outcomeOfCounts(run.counts)], recordings: [run.recordings?.state ?? 'unknown'], at: run.endedAtMs,
|
|
741
745
|
};
|
|
742
746
|
}
|
|
743
747
|
/**
|
|
@@ -752,7 +756,9 @@ export function fieldsOfRun(run) {
|
|
|
752
756
|
* list.results.map(r => [r.title, r.run, r.sha, r.status]);
|
|
753
757
|
* ```
|
|
754
758
|
*/
|
|
755
|
-
export function artifactList(history, version,
|
|
759
|
+
export function artifactList(history, version, asked = {}, page = {}) {
|
|
760
|
+
// Recording completeness is a property of a run: a recorded result is not asked about it.
|
|
761
|
+
const query = forArtifacts(asked);
|
|
756
762
|
const domains = new Map();
|
|
757
763
|
const domainOf = (path) => {
|
|
758
764
|
if (path === null)
|
package/dist/schema/src/api.d.ts
CHANGED
|
@@ -90,6 +90,7 @@ export declare const VideoRefSchema: z.ZodObject<{
|
|
|
90
90
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
91
91
|
recording: z.ZodOptional<z.ZodString>;
|
|
92
92
|
available: z.ZodBoolean;
|
|
93
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
93
94
|
scope: z.ZodOptional<z.ZodObject<{
|
|
94
95
|
surface: z.ZodOptional<z.ZodString>;
|
|
95
96
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -115,6 +116,7 @@ export declare const VideoCountsSchema: z.ZodObject<{
|
|
|
115
116
|
references: z.ZodNumber;
|
|
116
117
|
recordings: z.ZodNumber;
|
|
117
118
|
unavailable: z.ZodNumber;
|
|
119
|
+
missing: z.ZodOptional<z.ZodNumber>;
|
|
118
120
|
}, z.core.$loose>;
|
|
119
121
|
/** What a result carries beyond its outcome, as counts and short facts. Present only when there is something. */
|
|
120
122
|
export declare const EvidenceSummarySchema: z.ZodObject<{
|
|
@@ -141,6 +143,7 @@ export declare const EvidenceSummarySchema: z.ZodObject<{
|
|
|
141
143
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
142
144
|
recording: z.ZodOptional<z.ZodString>;
|
|
143
145
|
available: z.ZodBoolean;
|
|
146
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
144
147
|
scope: z.ZodOptional<z.ZodObject<{
|
|
145
148
|
surface: z.ZodOptional<z.ZodString>;
|
|
146
149
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -217,6 +220,7 @@ export declare const LayerHeaderSchema: z.ZodObject<{
|
|
|
217
220
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
218
221
|
recording: z.ZodOptional<z.ZodString>;
|
|
219
222
|
available: z.ZodBoolean;
|
|
223
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
220
224
|
scope: z.ZodOptional<z.ZodObject<{
|
|
221
225
|
surface: z.ZodOptional<z.ZodString>;
|
|
222
226
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -304,6 +308,7 @@ export declare const LayerRowSchema: z.ZodObject<{
|
|
|
304
308
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
305
309
|
recording: z.ZodOptional<z.ZodString>;
|
|
306
310
|
available: z.ZodBoolean;
|
|
311
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
307
312
|
scope: z.ZodOptional<z.ZodObject<{
|
|
308
313
|
surface: z.ZodOptional<z.ZodString>;
|
|
309
314
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -409,6 +414,7 @@ export declare const LayerRowsSchema: z.ZodObject<{
|
|
|
409
414
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
410
415
|
recording: z.ZodOptional<z.ZodString>;
|
|
411
416
|
available: z.ZodBoolean;
|
|
417
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
412
418
|
scope: z.ZodOptional<z.ZodObject<{
|
|
413
419
|
surface: z.ZodOptional<z.ZodString>;
|
|
414
420
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -516,6 +522,7 @@ export declare const LayerEvidenceSchema: z.ZodObject<{
|
|
|
516
522
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
517
523
|
recording: z.ZodOptional<z.ZodString>;
|
|
518
524
|
available: z.ZodBoolean;
|
|
525
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
519
526
|
scope: z.ZodOptional<z.ZodObject<{
|
|
520
527
|
surface: z.ZodOptional<z.ZodString>;
|
|
521
528
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -617,6 +624,7 @@ export declare const LayerEvidenceSchema: z.ZodObject<{
|
|
|
617
624
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
618
625
|
recording: z.ZodOptional<z.ZodString>;
|
|
619
626
|
available: z.ZodBoolean;
|
|
627
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
620
628
|
scope: z.ZodOptional<z.ZodObject<{
|
|
621
629
|
surface: z.ZodOptional<z.ZodString>;
|
|
622
630
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -713,6 +721,7 @@ export declare const EffectiveEvidenceSchema: z.ZodObject<{
|
|
|
713
721
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
714
722
|
recording: z.ZodOptional<z.ZodString>;
|
|
715
723
|
available: z.ZodBoolean;
|
|
724
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
716
725
|
scope: z.ZodOptional<z.ZodObject<{
|
|
717
726
|
surface: z.ZodOptional<z.ZodString>;
|
|
718
727
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -814,6 +823,7 @@ export declare const EffectiveEvidenceSchema: z.ZodObject<{
|
|
|
814
823
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
815
824
|
recording: z.ZodOptional<z.ZodString>;
|
|
816
825
|
available: z.ZodBoolean;
|
|
826
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
817
827
|
scope: z.ZodOptional<z.ZodObject<{
|
|
818
828
|
surface: z.ZodOptional<z.ZodString>;
|
|
819
829
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -931,6 +941,7 @@ export declare const EffectiveDeltaSchema: z.ZodObject<{
|
|
|
931
941
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
932
942
|
recording: z.ZodOptional<z.ZodString>;
|
|
933
943
|
available: z.ZodBoolean;
|
|
944
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
934
945
|
scope: z.ZodOptional<z.ZodObject<{
|
|
935
946
|
surface: z.ZodOptional<z.ZodString>;
|
|
936
947
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -1032,6 +1043,7 @@ export declare const EffectiveDeltaSchema: z.ZodObject<{
|
|
|
1032
1043
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1033
1044
|
recording: z.ZodOptional<z.ZodString>;
|
|
1034
1045
|
available: z.ZodBoolean;
|
|
1046
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
1035
1047
|
scope: z.ZodOptional<z.ZodObject<{
|
|
1036
1048
|
surface: z.ZodOptional<z.ZodString>;
|
|
1037
1049
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -1141,6 +1153,7 @@ export declare const EvidencePageSchema: z.ZodObject<{
|
|
|
1141
1153
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1142
1154
|
recording: z.ZodOptional<z.ZodString>;
|
|
1143
1155
|
available: z.ZodBoolean;
|
|
1156
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
1144
1157
|
scope: z.ZodOptional<z.ZodObject<{
|
|
1145
1158
|
surface: z.ZodOptional<z.ZodString>;
|
|
1146
1159
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -1721,6 +1734,7 @@ export declare const ReviewSnapshotSchema: z.ZodObject<{
|
|
|
1721
1734
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1722
1735
|
recording: z.ZodOptional<z.ZodString>;
|
|
1723
1736
|
available: z.ZodBoolean;
|
|
1737
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
1724
1738
|
scope: z.ZodOptional<z.ZodObject<{
|
|
1725
1739
|
surface: z.ZodOptional<z.ZodString>;
|
|
1726
1740
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -1784,6 +1798,7 @@ export declare const ReviewEntrySchema: z.ZodObject<{
|
|
|
1784
1798
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1785
1799
|
recording: z.ZodOptional<z.ZodString>;
|
|
1786
1800
|
available: z.ZodBoolean;
|
|
1801
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
1787
1802
|
scope: z.ZodOptional<z.ZodObject<{
|
|
1788
1803
|
surface: z.ZodOptional<z.ZodString>;
|
|
1789
1804
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -1866,6 +1881,7 @@ export declare const ReviewCollectionSchema: z.ZodObject<{
|
|
|
1866
1881
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1867
1882
|
recording: z.ZodOptional<z.ZodString>;
|
|
1868
1883
|
available: z.ZodBoolean;
|
|
1884
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
1869
1885
|
scope: z.ZodOptional<z.ZodObject<{
|
|
1870
1886
|
surface: z.ZodOptional<z.ZodString>;
|
|
1871
1887
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -2025,6 +2041,7 @@ export declare const ReviewCollectionDetailSchema: z.ZodObject<{
|
|
|
2025
2041
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2026
2042
|
recording: z.ZodOptional<z.ZodString>;
|
|
2027
2043
|
available: z.ZodBoolean;
|
|
2044
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
2028
2045
|
scope: z.ZodOptional<z.ZodObject<{
|
|
2029
2046
|
surface: z.ZodOptional<z.ZodString>;
|
|
2030
2047
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -2156,6 +2173,7 @@ export declare const ReviewManifestSchema: z.ZodObject<{
|
|
|
2156
2173
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2157
2174
|
recording: z.ZodOptional<z.ZodString>;
|
|
2158
2175
|
available: z.ZodBoolean;
|
|
2176
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
2159
2177
|
scope: z.ZodOptional<z.ZodObject<{
|
|
2160
2178
|
surface: z.ZodOptional<z.ZodString>;
|
|
2161
2179
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -2284,6 +2302,7 @@ export declare const TestResultEntrySchema: z.ZodObject<{
|
|
|
2284
2302
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2285
2303
|
recording: z.ZodOptional<z.ZodString>;
|
|
2286
2304
|
available: z.ZodBoolean;
|
|
2305
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
2287
2306
|
scope: z.ZodOptional<z.ZodObject<{
|
|
2288
2307
|
surface: z.ZodOptional<z.ZodString>;
|
|
2289
2308
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -2394,6 +2413,7 @@ export declare const TestSummarySchema: z.ZodObject<{
|
|
|
2394
2413
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2395
2414
|
recording: z.ZodOptional<z.ZodString>;
|
|
2396
2415
|
available: z.ZodBoolean;
|
|
2416
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
2397
2417
|
scope: z.ZodOptional<z.ZodObject<{
|
|
2398
2418
|
surface: z.ZodOptional<z.ZodString>;
|
|
2399
2419
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -2700,6 +2720,7 @@ export declare const TestCatalogSchema: z.ZodObject<{
|
|
|
2700
2720
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2701
2721
|
recording: z.ZodOptional<z.ZodString>;
|
|
2702
2722
|
available: z.ZodBoolean;
|
|
2723
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
2703
2724
|
scope: z.ZodOptional<z.ZodObject<{
|
|
2704
2725
|
surface: z.ZodOptional<z.ZodString>;
|
|
2705
2726
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -2938,6 +2959,7 @@ export declare const TestHistorySchema: z.ZodObject<{
|
|
|
2938
2959
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2939
2960
|
recording: z.ZodOptional<z.ZodString>;
|
|
2940
2961
|
available: z.ZodBoolean;
|
|
2962
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
2941
2963
|
scope: z.ZodOptional<z.ZodObject<{
|
|
2942
2964
|
surface: z.ZodOptional<z.ZodString>;
|
|
2943
2965
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -3066,6 +3088,7 @@ export declare const TestHistorySchema: z.ZodObject<{
|
|
|
3066
3088
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3067
3089
|
recording: z.ZodOptional<z.ZodString>;
|
|
3068
3090
|
available: z.ZodBoolean;
|
|
3091
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
3069
3092
|
scope: z.ZodOptional<z.ZodObject<{
|
|
3070
3093
|
surface: z.ZodOptional<z.ZodString>;
|
|
3071
3094
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -3267,6 +3290,21 @@ export declare const ReportRunSchema: z.ZodObject<{
|
|
|
3267
3290
|
references: z.ZodNumber;
|
|
3268
3291
|
recordings: z.ZodNumber;
|
|
3269
3292
|
unavailable: z.ZodNumber;
|
|
3293
|
+
missing: z.ZodOptional<z.ZodNumber>;
|
|
3294
|
+
}, z.core.$loose>>;
|
|
3295
|
+
recordings: z.ZodOptional<z.ZodObject<{
|
|
3296
|
+
state: z.ZodEnum<{
|
|
3297
|
+
unknown: "unknown";
|
|
3298
|
+
complete: "complete";
|
|
3299
|
+
incomplete: "incomplete";
|
|
3300
|
+
"none-expected": "none-expected";
|
|
3301
|
+
}>;
|
|
3302
|
+
expected: z.ZodNumber;
|
|
3303
|
+
published: z.ZodNumber;
|
|
3304
|
+
skipped: z.ZodNumber;
|
|
3305
|
+
unresolved: z.ZodNumber;
|
|
3306
|
+
notApplicable: z.ZodNumber;
|
|
3307
|
+
layersWithoutReceipt: z.ZodNumber;
|
|
3270
3308
|
}, z.core.$loose>>;
|
|
3271
3309
|
attachments: z.ZodOptional<z.ZodNumber>;
|
|
3272
3310
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -3313,6 +3351,10 @@ export declare const QueryFacetsSchema: z.ZodObject<{
|
|
|
3313
3351
|
value: z.ZodString;
|
|
3314
3352
|
count: z.ZodNumber;
|
|
3315
3353
|
}, z.core.$loose>>>;
|
|
3354
|
+
recordings: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
3355
|
+
value: z.ZodString;
|
|
3356
|
+
count: z.ZodNumber;
|
|
3357
|
+
}, z.core.$loose>>>;
|
|
3316
3358
|
}, z.core.$loose>;
|
|
3317
3359
|
/** `GET /api/reports/runs`: runs, newest first. */
|
|
3318
3360
|
export declare const RunListSchema: z.ZodObject<{
|
|
@@ -3354,6 +3396,21 @@ export declare const RunListSchema: z.ZodObject<{
|
|
|
3354
3396
|
references: z.ZodNumber;
|
|
3355
3397
|
recordings: z.ZodNumber;
|
|
3356
3398
|
unavailable: z.ZodNumber;
|
|
3399
|
+
missing: z.ZodOptional<z.ZodNumber>;
|
|
3400
|
+
}, z.core.$loose>>;
|
|
3401
|
+
recordings: z.ZodOptional<z.ZodObject<{
|
|
3402
|
+
state: z.ZodEnum<{
|
|
3403
|
+
unknown: "unknown";
|
|
3404
|
+
complete: "complete";
|
|
3405
|
+
incomplete: "incomplete";
|
|
3406
|
+
"none-expected": "none-expected";
|
|
3407
|
+
}>;
|
|
3408
|
+
expected: z.ZodNumber;
|
|
3409
|
+
published: z.ZodNumber;
|
|
3410
|
+
skipped: z.ZodNumber;
|
|
3411
|
+
unresolved: z.ZodNumber;
|
|
3412
|
+
notApplicable: z.ZodNumber;
|
|
3413
|
+
layersWithoutReceipt: z.ZodNumber;
|
|
3357
3414
|
}, z.core.$loose>>;
|
|
3358
3415
|
attachments: z.ZodOptional<z.ZodNumber>;
|
|
3359
3416
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -3396,6 +3453,10 @@ export declare const RunListSchema: z.ZodObject<{
|
|
|
3396
3453
|
value: z.ZodString;
|
|
3397
3454
|
count: z.ZodNumber;
|
|
3398
3455
|
}, z.core.$loose>>>;
|
|
3456
|
+
recordings: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
3457
|
+
value: z.ZodString;
|
|
3458
|
+
count: z.ZodNumber;
|
|
3459
|
+
}, z.core.$loose>>>;
|
|
3399
3460
|
}, z.core.$loose>>;
|
|
3400
3461
|
}, z.core.$loose>;
|
|
3401
3462
|
/** One recorded result that carries evidence: where and when it was recorded and what it carries. */
|
|
@@ -3435,6 +3496,7 @@ export declare const ArtifactResultSchema: z.ZodObject<{
|
|
|
3435
3496
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3436
3497
|
recording: z.ZodOptional<z.ZodString>;
|
|
3437
3498
|
available: z.ZodBoolean;
|
|
3499
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
3438
3500
|
scope: z.ZodOptional<z.ZodObject<{
|
|
3439
3501
|
surface: z.ZodOptional<z.ZodString>;
|
|
3440
3502
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -3505,6 +3567,7 @@ export declare const ArtifactListSchema: z.ZodObject<{
|
|
|
3505
3567
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3506
3568
|
recording: z.ZodOptional<z.ZodString>;
|
|
3507
3569
|
available: z.ZodBoolean;
|
|
3570
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
3508
3571
|
scope: z.ZodOptional<z.ZodObject<{
|
|
3509
3572
|
surface: z.ZodOptional<z.ZodString>;
|
|
3510
3573
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -3566,6 +3629,10 @@ export declare const ArtifactListSchema: z.ZodObject<{
|
|
|
3566
3629
|
value: z.ZodString;
|
|
3567
3630
|
count: z.ZodNumber;
|
|
3568
3631
|
}, z.core.$loose>>>;
|
|
3632
|
+
recordings: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
3633
|
+
value: z.ZodString;
|
|
3634
|
+
count: z.ZodNumber;
|
|
3635
|
+
}, z.core.$loose>>>;
|
|
3569
3636
|
}, z.core.$loose>;
|
|
3570
3637
|
}, z.core.$loose>;
|
|
3571
3638
|
/** `GET /api/reports/runs/detail`: one run and its last result for every test, environment and producer it recorded. */
|
|
@@ -3607,6 +3674,21 @@ export declare const RunDetailSchema: z.ZodObject<{
|
|
|
3607
3674
|
references: z.ZodNumber;
|
|
3608
3675
|
recordings: z.ZodNumber;
|
|
3609
3676
|
unavailable: z.ZodNumber;
|
|
3677
|
+
missing: z.ZodOptional<z.ZodNumber>;
|
|
3678
|
+
}, z.core.$loose>>;
|
|
3679
|
+
recordings: z.ZodOptional<z.ZodObject<{
|
|
3680
|
+
state: z.ZodEnum<{
|
|
3681
|
+
unknown: "unknown";
|
|
3682
|
+
complete: "complete";
|
|
3683
|
+
incomplete: "incomplete";
|
|
3684
|
+
"none-expected": "none-expected";
|
|
3685
|
+
}>;
|
|
3686
|
+
expected: z.ZodNumber;
|
|
3687
|
+
published: z.ZodNumber;
|
|
3688
|
+
skipped: z.ZodNumber;
|
|
3689
|
+
unresolved: z.ZodNumber;
|
|
3690
|
+
notApplicable: z.ZodNumber;
|
|
3691
|
+
layersWithoutReceipt: z.ZodNumber;
|
|
3610
3692
|
}, z.core.$loose>>;
|
|
3611
3693
|
attachments: z.ZodOptional<z.ZodNumber>;
|
|
3612
3694
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -3639,6 +3721,7 @@ export declare const RunDetailSchema: z.ZodObject<{
|
|
|
3639
3721
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3640
3722
|
recording: z.ZodOptional<z.ZodString>;
|
|
3641
3723
|
available: z.ZodBoolean;
|
|
3724
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
3642
3725
|
scope: z.ZodOptional<z.ZodObject<{
|
|
3643
3726
|
surface: z.ZodOptional<z.ZodString>;
|
|
3644
3727
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -3676,6 +3759,7 @@ export declare const RunDetailSchema: z.ZodObject<{
|
|
|
3676
3759
|
references: z.ZodNumber;
|
|
3677
3760
|
recordings: z.ZodNumber;
|
|
3678
3761
|
unavailable: z.ZodNumber;
|
|
3762
|
+
missing: z.ZodOptional<z.ZodNumber>;
|
|
3679
3763
|
}, z.core.$loose>>;
|
|
3680
3764
|
}, z.core.$loose>>>;
|
|
3681
3765
|
}, z.core.$loose>;
|
package/dist/schema/src/api.js
CHANGED
|
@@ -71,13 +71,15 @@ export const VideoRefSchema = z.looseObject({
|
|
|
71
71
|
tags: z.array(z.string()).optional().describe('The normalized tags of this attachment itself. Absent when it has none (and in documents of older servers)'),
|
|
72
72
|
recording: z.string().optional().describe('What identifies the bytes; references with the same value are one recording. Absent when it cannot be played'),
|
|
73
73
|
available: z.boolean().describe('False when the reference names no bytes: no bundle key, address or inline text, or a bundle key that the layer\'s own bundle does not hold'),
|
|
74
|
+
reason: z.string().optional().describe('Why it is unavailable, when the report can tell: `not-in-bundle` is a file the layer names but does not hold (stored, then gone). An open vocabulary: treat an unknown reason as plain unavailable'),
|
|
74
75
|
scope: EvidenceScopeSchema.optional().describe('What this recording shows as its producer declared it: its own `scope`, else its attempt\'s, check\'s, part\'s or layer\'s. Absent: the scope is unknown, never live, physical or audible')
|
|
75
76
|
});
|
|
76
77
|
/** Video references as counts: how many are referenced, how many distinct recordings can be played, how many cannot. */
|
|
77
78
|
export const VideoCountsSchema = z.looseObject({
|
|
78
79
|
references: z.number().int().nonnegative().describe('Every reference to a video; identical bytes referenced twice count twice'),
|
|
79
80
|
recordings: z.number().int().nonnegative().describe('Distinct playable recordings'),
|
|
80
|
-
unavailable: z.number().int().nonnegative().describe('References that name no bytes, or bytes the layer does not hold')
|
|
81
|
+
unavailable: z.number().int().nonnegative().describe('References that name no bytes, or bytes the layer does not hold'),
|
|
82
|
+
missing: z.number().int().positive().optional().describe('Of `unavailable`, those that name a file the layer\'s bundle does not hold (stored, then gone). Absent when there are none')
|
|
81
83
|
});
|
|
82
84
|
/** What a result carries beyond its outcome, as counts and short facts. Present only when there is something. */
|
|
83
85
|
export const EvidenceSummarySchema = z.looseObject({
|
|
@@ -625,6 +627,12 @@ export const ReportRunSchema = z.looseObject({
|
|
|
625
627
|
totalDurationMs: z.number().nullable(),
|
|
626
628
|
failing: z.array(z.looseObject({ key: z.string(), title: z.string(), environment: z.string().nullable(), detail: z.string() })),
|
|
627
629
|
videos: VideoCountsSchema.optional().describe('Its videos, from its layers and the last result of each test. Absent when it has none or the report carries no video information'),
|
|
630
|
+
recordings: z.looseObject({
|
|
631
|
+
state: z.enum(['complete', 'incomplete', 'none-expected', 'unknown']).describe('`incomplete` when an expected recording was skipped or unresolved; else `unknown` when a layer declared no expectations; else `complete` when something was expected and `none-expected` when nothing was'),
|
|
632
|
+
expected: z.number().int().nonnegative(), published: z.number().int().nonnegative().describe('Of the expected recordings, uploaded or referenced by address'),
|
|
633
|
+
skipped: z.number().int().nonnegative(), unresolved: z.number().int().nonnegative(), notApplicable: z.number().int().nonnegative(),
|
|
634
|
+
layersWithoutReceipt: z.number().int().nonnegative().describe('Layers of the run that declared no recording expectations: nothing is claimed for them')
|
|
635
|
+
}).optional().describe('Whether the recordings its layers expected were published, apart from its outcomes. Absent when no layer declared an expectation: its completeness is unknown, never complete. Matched by the `recordings` filter'),
|
|
628
636
|
attachments: z.number().int().positive().optional().describe('Files attached to the run itself, in its layers, not to a check. Absent when there are none'),
|
|
629
637
|
artifactTags: z.array(z.string()).optional().describe('The normalized tags of the attachments of its results, sorted and distinct. Absent when none is tagged, and in reports of older servers'),
|
|
630
638
|
tags: z.array(z.string()).optional().describe('The tags of its checks and layers, which its attachments inherit (what `inherited=1` also matches). Absent when none'),
|
|
@@ -637,7 +645,8 @@ export const QueryFacetValueSchema = z.looseObject({ value: z.string(), count: z
|
|
|
637
645
|
export const QueryFacetsSchema = z.looseObject({
|
|
638
646
|
artifactTags: z.array(QueryFacetValueSchema), types: z.array(QueryFacetValueSchema), labels: z.array(QueryFacetValueSchema).describe('Values are `key=value`'),
|
|
639
647
|
environments: z.array(QueryFacetValueSchema), producers: z.array(QueryFacetValueSchema), branches: z.array(QueryFacetValueSchema), outcomes: z.array(QueryFacetValueSchema),
|
|
640
|
-
domains: z.array(QueryFacetValueSchema).optional().describe('Only for artifacts: runs have no domain')
|
|
648
|
+
domains: z.array(QueryFacetValueSchema).optional().describe('Only for artifacts: runs have no domain'),
|
|
649
|
+
recordings: z.array(QueryFacetValueSchema).optional().describe('Only for runs: `complete`, `incomplete`, `none-expected` and `unknown` with how many runs have each. Absent on servers that predate the filter')
|
|
641
650
|
});
|
|
642
651
|
/** `GET /api/reports/runs`: runs, newest first. */
|
|
643
652
|
export const RunListSchema = z.looseObject({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module Command results (`--format json`)
|
|
3
3
|
*
|
|
4
|
-
* What `atlas report publish`, `stream`, `merge` and `
|
|
4
|
+
* What `atlas report publish`, `stream`, `merge`, `doctor` and `verify-recordings` print on standard output with `--format json` (alias
|
|
5
5
|
* `--json`), and what any `atlas` command prints on standard error for a command that was wrong: one JSON document,
|
|
6
6
|
* so an agent or a script never has to parse prose. (`status` and `policy` already print documents:
|
|
7
7
|
* `ReportStatusSchema`, and an IAM policy.) Each is also published as a JSON Schema.
|
|
@@ -152,6 +152,36 @@ export declare const DoctorResultSchema: z.ZodObject<{
|
|
|
152
152
|
}, z.core.$loose>>;
|
|
153
153
|
}, z.core.$loose>>;
|
|
154
154
|
}, z.core.$loose>;
|
|
155
|
+
/** A published video that could not be read back from the store as published (see `atlas report verify-recordings`). */
|
|
156
|
+
export declare const RecordingGapSchema: z.ZodObject<{
|
|
157
|
+
layer: z.ZodString;
|
|
158
|
+
check: z.ZodNullable<z.ZodString>;
|
|
159
|
+
name: z.ZodString;
|
|
160
|
+
bundleKey: z.ZodString;
|
|
161
|
+
problem: z.ZodString;
|
|
162
|
+
reason: z.ZodString;
|
|
163
|
+
}, z.core.$loose>;
|
|
164
|
+
/**
|
|
165
|
+
* What `atlas report verify-recordings --format json` prints: whether the videos the layers published can still be read
|
|
166
|
+
* back from the store as they were published. It describes stored bytes, never playback in a browser, and it never changes
|
|
167
|
+
* a check\'s result.
|
|
168
|
+
*/
|
|
169
|
+
export declare const VerifyRecordingsResultSchema: z.ZodObject<{
|
|
170
|
+
ok: z.ZodBoolean;
|
|
171
|
+
layers: z.ZodNumber;
|
|
172
|
+
checked: z.ZodNumber;
|
|
173
|
+
verified: z.ZodNumber;
|
|
174
|
+
referenced: z.ZodNumber;
|
|
175
|
+
gaps: z.ZodArray<z.ZodObject<{
|
|
176
|
+
layer: z.ZodString;
|
|
177
|
+
check: z.ZodNullable<z.ZodString>;
|
|
178
|
+
name: z.ZodString;
|
|
179
|
+
bundleKey: z.ZodString;
|
|
180
|
+
problem: z.ZodString;
|
|
181
|
+
reason: z.ZodString;
|
|
182
|
+
}, z.core.$loose>>;
|
|
183
|
+
notices: z.ZodArray<z.ZodString>;
|
|
184
|
+
}, z.core.$loose>;
|
|
155
185
|
/** What any `atlas` command prints on standard error, with `--format json`, when the command itself was wrong (exit code 2). */
|
|
156
186
|
export declare const CommandErrorSchema: z.ZodObject<{
|
|
157
187
|
ok: z.ZodLiteral<false>;
|
|
@@ -532,6 +562,26 @@ export declare const CLI_RESULTS: {
|
|
|
532
562
|
}, z.core.$loose>>;
|
|
533
563
|
}, z.core.$loose>;
|
|
534
564
|
};
|
|
565
|
+
readonly verifyRecordings: {
|
|
566
|
+
readonly command: "atlas report verify-recordings";
|
|
567
|
+
readonly schemaName: "verify-recordings-result";
|
|
568
|
+
readonly schema: z.ZodObject<{
|
|
569
|
+
ok: z.ZodBoolean;
|
|
570
|
+
layers: z.ZodNumber;
|
|
571
|
+
checked: z.ZodNumber;
|
|
572
|
+
verified: z.ZodNumber;
|
|
573
|
+
referenced: z.ZodNumber;
|
|
574
|
+
gaps: z.ZodArray<z.ZodObject<{
|
|
575
|
+
layer: z.ZodString;
|
|
576
|
+
check: z.ZodNullable<z.ZodString>;
|
|
577
|
+
name: z.ZodString;
|
|
578
|
+
bundleKey: z.ZodString;
|
|
579
|
+
problem: z.ZodString;
|
|
580
|
+
reason: z.ZodString;
|
|
581
|
+
}, z.core.$loose>>;
|
|
582
|
+
notices: z.ZodArray<z.ZodString>;
|
|
583
|
+
}, z.core.$loose>;
|
|
584
|
+
};
|
|
535
585
|
readonly error: {
|
|
536
586
|
readonly command: "a command that was wrong (standard error)";
|
|
537
587
|
readonly schemaName: "command-error";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module Command results (`--format json`)
|
|
3
3
|
*
|
|
4
|
-
* What `atlas report publish`, `stream`, `merge` and `
|
|
4
|
+
* What `atlas report publish`, `stream`, `merge`, `doctor` and `verify-recordings` print on standard output with `--format json` (alias
|
|
5
5
|
* `--json`), and what any `atlas` command prints on standard error for a command that was wrong: one JSON document,
|
|
6
6
|
* so an agent or a script never has to parse prose. (`status` and `policy` already print documents:
|
|
7
7
|
* `ReportStatusSchema`, and an IAM policy.) Each is also published as a JSON Schema.
|
|
@@ -75,6 +75,29 @@ export const DoctorResultSchema = z.looseObject({
|
|
|
75
75
|
ok: z.boolean().describe('True when every check of every store passed (otherwise the exit code is 1)'),
|
|
76
76
|
stores: z.array(z.looseObject({ id: z.string(), checks: z.array(DoctorCheckSchema) }))
|
|
77
77
|
});
|
|
78
|
+
/** A published video that could not be read back from the store as published (see `atlas report verify-recordings`). */
|
|
79
|
+
export const RecordingGapSchema = z.looseObject({
|
|
80
|
+
layer: z.string().describe('The layer that holds the video'),
|
|
81
|
+
check: z.string().nullable().describe('The check that holds it, or null for a video attached to the layer or a part'),
|
|
82
|
+
name: z.string().describe('The attachment\'s name'),
|
|
83
|
+
bundleKey: z.string().describe('Its key in the layer\'s bundle (`attachments/<sha256>`)'),
|
|
84
|
+
problem: z.string().describe('`not-in-bundle` (the layer names a file its bundle does not list), `blob-missing` (a blob holding it is gone: a 404 when played), `unreadable` (the store could not be read: not proof it is gone), `size-mismatch`, `checksum-mismatch` or `undecodable` (empty, or not the container its media type names). An open vocabulary: treat an unknown problem as a gap'),
|
|
85
|
+
reason: z.string().describe('A short explanation without tokens, paths or payload')
|
|
86
|
+
});
|
|
87
|
+
/**
|
|
88
|
+
* What `atlas report verify-recordings --format json` prints: whether the videos the layers published can still be read
|
|
89
|
+
* back from the store as they were published. It describes stored bytes, never playback in a browser, and it never changes
|
|
90
|
+
* a check\'s result.
|
|
91
|
+
*/
|
|
92
|
+
export const VerifyRecordingsResultSchema = z.looseObject({
|
|
93
|
+
ok: z.boolean().describe('True when no layer has a gap and every layer could be read (otherwise the exit code is 1). Test results are unaffected either way'),
|
|
94
|
+
layers: z.number().int().nonnegative().describe('Layers examined'),
|
|
95
|
+
checked: z.number().int().nonnegative().describe('Videos read back from the store (those that name a bundle key)'),
|
|
96
|
+
verified: z.number().int().nonnegative().describe('Of those, the ones that passed every check'),
|
|
97
|
+
referenced: z.number().int().nonnegative().describe('Videos given only by address, which Atlas holds no bytes for and does not check'),
|
|
98
|
+
gaps: z.array(RecordingGapSchema).describe('Every video that is missing, unreadable, corrupt or not the container it claims. Re-publish the layer\'s recordings to repair them'),
|
|
99
|
+
notices: z.array(z.string()).describe('Layers that could not be read at all: their recordings are unknown, never verified')
|
|
100
|
+
});
|
|
78
101
|
/** What any `atlas` command prints on standard error, with `--format json`, when the command itself was wrong (exit code 2). */
|
|
79
102
|
export const CommandErrorSchema = z.looseObject({
|
|
80
103
|
ok: z.literal(false),
|
|
@@ -142,5 +165,6 @@ export const CLI_RESULTS = {
|
|
|
142
165
|
merge: { command: 'atlas report merge', schemaName: 'merge-result', schema: MergeResultSchema },
|
|
143
166
|
doctor: { command: 'atlas report doctor', schemaName: 'doctor-result', schema: DoctorResultSchema },
|
|
144
167
|
status: { command: 'atlas report status', schemaName: 'report-status', schema: ReportStatusSchema },
|
|
168
|
+
verifyRecordings: { command: 'atlas report verify-recordings', schemaName: 'verify-recordings-result', schema: VerifyRecordingsResultSchema },
|
|
145
169
|
error: { command: 'a command that was wrong (standard error)', schemaName: 'command-error', schema: CommandErrorSchema }
|
|
146
170
|
};
|
|
@@ -427,6 +427,7 @@ const BASE_OPERATIONS = [
|
|
|
427
427
|
{ name: 'branch', in: 'query', description: 'Branches.', schema: str },
|
|
428
428
|
{ name: 'sha', in: 'query', description: 'Revisions: a full commit id or a prefix of at least seven characters.', schema: str },
|
|
429
429
|
{ name: 'outcome', in: 'query', description: 'Statuses: `passed`, `failed`, `running`, `not-run`. A run\'s outcome is `failed` when any result failed, else `running`, else `passed`, else `not-run`.', schema: str },
|
|
430
|
+
{ name: 'recordings', in: 'query', description: 'Recording completeness of the run, apart from its outcome: `complete`, `incomplete`, `none-expected` or `unknown` (a run whose layers declared no recording expectations is `unknown`, never `complete`). Repeatable or comma-separated. Answered from the layers\' receipts; no recording is read. A server that does not know it ignores it and does not name it in `filters`.', schema: str },
|
|
430
431
|
{ name: 'q', in: 'query', description: 'Words that must all appear in the title, id, spec, branch, producer, environment, tags or labels.', schema: str },
|
|
431
432
|
{ name: 'since', in: 'query', description: 'Only records at or after this time: epoch milliseconds or an ISO date (a date alone is UTC). A result\'s recording time; a run\'s end.', schema: str },
|
|
432
433
|
{ name: 'until', in: 'query', description: 'Only records at or before this time (same forms as `since`).', schema: str },
|
package/docs/agents.md
CHANGED
|
@@ -163,6 +163,7 @@ JSON Schema (`@crvouga/atlas/schemas/<name>.schema.json`, draft 2020-12):
|
|
|
163
163
|
| `atlas report merge` | `merge-result` |
|
|
164
164
|
| `atlas report doctor` | `doctor-result` |
|
|
165
165
|
| `atlas report status` | `report-status` |
|
|
166
|
+
| `atlas report verify-recordings` | `verify-recordings-result` |
|
|
166
167
|
| `a command that was wrong (standard error)` | `command-error` |
|
|
167
168
|
<!-- /generated:json-command-schemas -->
|
|
168
169
|
|
package/docs/reference/cli.md
CHANGED
|
@@ -105,6 +105,8 @@ atlas report — layered evidence for any kind of spec
|
|
|
105
105
|
[--specs <dir>] [--format text|json|markdown]
|
|
106
106
|
[--require-environments a,b] [--require-all-specs]
|
|
107
107
|
[--branch <name>]... [--ignore-modified]
|
|
108
|
+
atlas report verify-recordings [--store <dir|s3://…|id=url>]... [--backends <module>] [--layer <id>]...
|
|
109
|
+
[--limit <n>] [--branch <name>]... [--ignore-modified] [--format text|json]
|
|
108
110
|
atlas report merge [--store …]... [--backends <module>] --into <dir|s3://…>
|
|
109
111
|
atlas report doctor [--store …]... [--role publisher|reader|both]
|
|
110
112
|
atlas report policy --store s3://bucket/prefix [--role publisher|reader|both]
|
|
@@ -148,6 +150,13 @@ atlas report — layered evidence for any kind of spec
|
|
|
148
150
|
--require-all-specs fail while any spec has no results
|
|
149
151
|
--branch <name> only layers recorded on this branch (repeatable)
|
|
150
152
|
--ignore-modified leave out layers from modified checkouts and unknown origins
|
|
153
|
+
verify-recordings Read back the videos the layers published and check they are still there as published: the
|
|
154
|
+
layer still lists the file, its blob is still stored, its size and SHA-256 are the recorded ones, and it
|
|
155
|
+
begins like the container its media type names. Exit 1 when any video is missing, unreadable, corrupt or
|
|
156
|
+
not that container, naming the layer and check; test results are never changed. This checks stored bytes,
|
|
157
|
+
not playback in a browser. Videos given only by address are counted, not checked.
|
|
158
|
+
--layer <id> only the layer whose id starts with this (repeatable; at least 7 digits)
|
|
159
|
+
--limit <n> only the newest n layers
|
|
151
160
|
merge Copy the layers of several stores into one.
|
|
152
161
|
doctor Check that a store works: credentials, listing, writing, and what it holds.
|
|
153
162
|
policy Print the least-privilege IAM policy for publishers, readers, or both.
|
|
@@ -156,8 +165,8 @@ atlas report — layered evidence for any kind of spec
|
|
|
156
165
|
{ id, label?, store } (or a function returning it): a device lab, anything
|
|
157
166
|
that implements ObjectStore.
|
|
158
167
|
|
|
159
|
-
--format json (alias --json) publish, stream, merge, doctor and
|
|
160
|
-
(schemas: publish-result, stream-result, merge-result, doctor-result, report-status). A command
|
|
168
|
+
--format json (alias --json) publish, stream, merge, doctor, status and verify-recordings print one JSON document instead of prose
|
|
169
|
+
(schemas: publish-result, stream-result, merge-result, doctor-result, report-status, verify-recordings-result). A command
|
|
161
170
|
that is wrong is {"ok":false,"error":{"message":…,"code":"usage"}} on standard error.
|
|
162
171
|
A store may be an Atlas server (https://…): ATLAS_STORE=https://atlas.example.com, with ATLAS_TOKEN.
|
|
163
172
|
|
|
@@ -833,6 +833,7 @@ Every run, newest first: layers grouped by their CI run URL (else branch and com
|
|
|
833
833
|
- `branch` (query): Branches.
|
|
834
834
|
- `sha` (query): Revisions: a full commit id or a prefix of at least seven characters.
|
|
835
835
|
- `outcome` (query): Statuses: `passed`, `failed`, `running`, `not-run`. A run's outcome is `failed` when any result failed, else `running`, else `passed`, else `not-run`.
|
|
836
|
+
- `recordings` (query): Recording completeness of the run, apart from its outcome: `complete`, `incomplete`, `none-expected` or `unknown` (a run whose layers declared no recording expectations is `unknown`, never `complete`). Repeatable or comma-separated. Answered from the layers' receipts; no recording is read. A server that does not know it ignores it and does not name it in `filters`.
|
|
836
837
|
- `q` (query): Words that must all appear in the title, id, spec, branch, producer, environment, tags or labels.
|
|
837
838
|
- `since` (query): Only records at or after this time: epoch milliseconds or an ISO date (a date alone is UTC). A result's recording time; a run's end.
|
|
838
839
|
- `until` (query): Only records at or before this time (same forms as `since`).
|
|
@@ -861,6 +862,7 @@ Scoped to one project. The same project may be selected on the unprefixed API us
|
|
|
861
862
|
- `branch` (query): Branches.
|
|
862
863
|
- `sha` (query): Revisions: a full commit id or a prefix of at least seven characters.
|
|
863
864
|
- `outcome` (query): Statuses: `passed`, `failed`, `running`, `not-run`. A run's outcome is `failed` when any result failed, else `running`, else `passed`, else `not-run`.
|
|
865
|
+
- `recordings` (query): Recording completeness of the run, apart from its outcome: `complete`, `incomplete`, `none-expected` or `unknown` (a run whose layers declared no recording expectations is `unknown`, never `complete`). Repeatable or comma-separated. Answered from the layers' receipts; no recording is read. A server that does not know it ignores it and does not name it in `filters`.
|
|
864
866
|
- `q` (query): Words that must all appear in the title, id, spec, branch, producer, environment, tags or labels.
|
|
865
867
|
- `since` (query): Only records at or after this time: epoch milliseconds or an ISO date (a date alone is UTC). A result's recording time; a run's end.
|
|
866
868
|
- `until` (query): Only records at or before this time (same forms as `since`).
|