@crvouga/atlas 1.17.0 → 1.19.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 +14 -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 +19 -6
- package/dist/reports/src/evidence-types.d.ts +8 -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 +134 -0
- package/dist/schema/src/api.js +13 -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 +189 -9
- package/docs/reference/schema.md +19 -1
- package/docs/rich-evidence.md +33 -5
- package/docs/server.md +1 -1
- package/docs/ui.md +40 -1
- package/llms-full.txt +88 -9
- 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/report-run.schema.json +83 -0
- package/packages/schema/schemas/report-runs.schema.json +86 -0
- package/packages/schema/schemas/review-collection.schema.json +13 -0
- package/packages/schema/schemas/review-manifest.schema.json +13 -0
- package/packages/schema/schemas/test-catalog.schema.json +13 -0
- package/packages/schema/schemas/test-history.schema.json +26 -0
- package/packages/schema/schemas/verify-recordings-result.schema.json +97 -0
- package/packages/server/openapi.json +378 -0
- package/packages/visualizer/src/app/AppShell.tsx +2 -2
- package/packages/visualizer/src/app/router.tsx +25 -1
- package/packages/visualizer/src/components/Header.tsx +15 -4
- package/packages/visualizer/src/evidence/behavior-index.test.ts +119 -0
- package/packages/visualizer/src/evidence/behavior-index.ts +162 -0
- package/packages/visualizer/src/evidence/behavior-panel.tsx +36 -22
- package/packages/visualizer/src/evidence/behavior-return.test.ts +41 -0
- package/packages/visualizer/src/evidence/behavior-return.ts +59 -0
- package/packages/visualizer/src/evidence/behavior.ts +32 -1
- package/packages/visualizer/src/evidence/behaviors-page.tsx +465 -0
- package/packages/visualizer/src/evidence/feature-page.tsx +5 -26
- package/packages/visualizer/src/evidence/scoped-summary-view.tsx +110 -0
- package/packages/visualizer/src/evidence/scoped-summary.test.ts +62 -0
- package/packages/visualizer/src/evidence/scoped-summary.ts +118 -0
- package/packages/visualizer/src/evidence/spec-texts.ts +88 -0
- package/packages/visualizer/src/explorer/ArtifactsView.tsx +7 -6
- package/packages/visualizer/src/explorer/Explorer.tsx +1 -1
- package/packages/visualizer/src/explorer/RunsView.tsx +32 -7
- package/packages/visualizer/src/explorer/collections.tsx +5 -5
- package/packages/visualizer/src/explorer/filters.tsx +11 -3
- package/packages/visualizer/src/explorer/navigate.ts +17 -0
- package/packages/visualizer/src/explorer/playlist-entries.test.ts +10 -1
- package/packages/visualizer/src/explorer/playlist-entries.ts +10 -0
- package/packages/visualizer/src/explorer/playlist.tsx +43 -8
- package/packages/visualizer/src/explorer/search.ts +13 -3
- package/packages/visualizer/src/find/Finder.tsx +1 -62
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ArtifactFilter, type FilterFields, type FilterName, type QueryFacets } from './artifact-query.js';
|
|
2
2
|
import type { EvidenceMeasurement, EvidenceStatus, SpecEntry } from './explorer-types.js';
|
|
3
3
|
import type { EvidenceSummary, LayerEvidence, LayerHeader, LayerRow, StatusCounts, VideoCounts, VideoRef } from './evidence-types.js';
|
|
4
|
+
import { type RunRecordings } from './recording-receipt.js';
|
|
4
5
|
import { RecordedSpecs } from './recorded-specs.js';
|
|
5
6
|
/** The version of the documents this module writes (`TestCatalog`, `TestHistoryDocument`, `RunList`, `RunDetail`). Only optional fields are added within it. */
|
|
6
7
|
export declare const TEST_CATALOG_VERSION = 1;
|
|
@@ -287,6 +288,11 @@ export type RunSummary = {
|
|
|
287
288
|
* and references that cannot be played. Absent when it has none, and in a report that carries no video information.
|
|
288
289
|
*/
|
|
289
290
|
readonly videos?: VideoCounts;
|
|
291
|
+
/**
|
|
292
|
+
* Whether the recordings its layers expected were published, apart from its outcomes (see `runRecordings`). Absent when
|
|
293
|
+
* none of its layers declared a recording expectation: its completeness is unknown, never complete. Never changes a status.
|
|
294
|
+
*/
|
|
295
|
+
readonly recordings?: RunRecordings;
|
|
290
296
|
/**
|
|
291
297
|
* Files attached to the run itself, in its layers (and their parts), not to any one check: review movies, archives,
|
|
292
298
|
* summaries. All kinds, videos included. Absent when none, and in a report that carries no such information.
|
|
@@ -556,7 +562,7 @@ export declare function fieldsOfRun(run: RunSummary): FilterFields;
|
|
|
556
562
|
* list.results.map(r => [r.title, r.run, r.sha, r.status]);
|
|
557
563
|
* ```
|
|
558
564
|
*/
|
|
559
|
-
export declare function artifactList(history: TestHistory, version: string,
|
|
565
|
+
export declare function artifactList(history: TestHistory, version: string, asked?: ArtifactFilter, page?: {
|
|
560
566
|
readonly limit?: number;
|
|
561
567
|
readonly offset?: number;
|
|
562
568
|
readonly domainOf?: (specPath: string) => string | undefined;
|
|
@@ -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,9 @@ 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>;
|
|
94
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
95
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
93
96
|
scope: z.ZodOptional<z.ZodObject<{
|
|
94
97
|
surface: z.ZodOptional<z.ZodString>;
|
|
95
98
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -115,6 +118,7 @@ export declare const VideoCountsSchema: z.ZodObject<{
|
|
|
115
118
|
references: z.ZodNumber;
|
|
116
119
|
recordings: z.ZodNumber;
|
|
117
120
|
unavailable: z.ZodNumber;
|
|
121
|
+
missing: z.ZodOptional<z.ZodNumber>;
|
|
118
122
|
}, z.core.$loose>;
|
|
119
123
|
/** What a result carries beyond its outcome, as counts and short facts. Present only when there is something. */
|
|
120
124
|
export declare const EvidenceSummarySchema: z.ZodObject<{
|
|
@@ -141,6 +145,9 @@ export declare const EvidenceSummarySchema: z.ZodObject<{
|
|
|
141
145
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
142
146
|
recording: z.ZodOptional<z.ZodString>;
|
|
143
147
|
available: z.ZodBoolean;
|
|
148
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
149
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
150
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
144
151
|
scope: z.ZodOptional<z.ZodObject<{
|
|
145
152
|
surface: z.ZodOptional<z.ZodString>;
|
|
146
153
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -217,6 +224,9 @@ export declare const LayerHeaderSchema: z.ZodObject<{
|
|
|
217
224
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
218
225
|
recording: z.ZodOptional<z.ZodString>;
|
|
219
226
|
available: z.ZodBoolean;
|
|
227
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
228
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
229
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
220
230
|
scope: z.ZodOptional<z.ZodObject<{
|
|
221
231
|
surface: z.ZodOptional<z.ZodString>;
|
|
222
232
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -304,6 +314,9 @@ export declare const LayerRowSchema: z.ZodObject<{
|
|
|
304
314
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
305
315
|
recording: z.ZodOptional<z.ZodString>;
|
|
306
316
|
available: z.ZodBoolean;
|
|
317
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
318
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
319
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
307
320
|
scope: z.ZodOptional<z.ZodObject<{
|
|
308
321
|
surface: z.ZodOptional<z.ZodString>;
|
|
309
322
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -409,6 +422,9 @@ export declare const LayerRowsSchema: z.ZodObject<{
|
|
|
409
422
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
410
423
|
recording: z.ZodOptional<z.ZodString>;
|
|
411
424
|
available: z.ZodBoolean;
|
|
425
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
426
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
427
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
412
428
|
scope: z.ZodOptional<z.ZodObject<{
|
|
413
429
|
surface: z.ZodOptional<z.ZodString>;
|
|
414
430
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -516,6 +532,9 @@ export declare const LayerEvidenceSchema: z.ZodObject<{
|
|
|
516
532
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
517
533
|
recording: z.ZodOptional<z.ZodString>;
|
|
518
534
|
available: z.ZodBoolean;
|
|
535
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
536
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
537
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
519
538
|
scope: z.ZodOptional<z.ZodObject<{
|
|
520
539
|
surface: z.ZodOptional<z.ZodString>;
|
|
521
540
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -617,6 +636,9 @@ export declare const LayerEvidenceSchema: z.ZodObject<{
|
|
|
617
636
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
618
637
|
recording: z.ZodOptional<z.ZodString>;
|
|
619
638
|
available: z.ZodBoolean;
|
|
639
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
640
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
641
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
620
642
|
scope: z.ZodOptional<z.ZodObject<{
|
|
621
643
|
surface: z.ZodOptional<z.ZodString>;
|
|
622
644
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -713,6 +735,9 @@ export declare const EffectiveEvidenceSchema: z.ZodObject<{
|
|
|
713
735
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
714
736
|
recording: z.ZodOptional<z.ZodString>;
|
|
715
737
|
available: z.ZodBoolean;
|
|
738
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
739
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
740
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
716
741
|
scope: z.ZodOptional<z.ZodObject<{
|
|
717
742
|
surface: z.ZodOptional<z.ZodString>;
|
|
718
743
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -814,6 +839,9 @@ export declare const EffectiveEvidenceSchema: z.ZodObject<{
|
|
|
814
839
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
815
840
|
recording: z.ZodOptional<z.ZodString>;
|
|
816
841
|
available: z.ZodBoolean;
|
|
842
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
843
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
844
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
817
845
|
scope: z.ZodOptional<z.ZodObject<{
|
|
818
846
|
surface: z.ZodOptional<z.ZodString>;
|
|
819
847
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -931,6 +959,9 @@ export declare const EffectiveDeltaSchema: z.ZodObject<{
|
|
|
931
959
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
932
960
|
recording: z.ZodOptional<z.ZodString>;
|
|
933
961
|
available: z.ZodBoolean;
|
|
962
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
963
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
964
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
934
965
|
scope: z.ZodOptional<z.ZodObject<{
|
|
935
966
|
surface: z.ZodOptional<z.ZodString>;
|
|
936
967
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -1032,6 +1063,9 @@ export declare const EffectiveDeltaSchema: z.ZodObject<{
|
|
|
1032
1063
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1033
1064
|
recording: z.ZodOptional<z.ZodString>;
|
|
1034
1065
|
available: z.ZodBoolean;
|
|
1066
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
1067
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
1068
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
1035
1069
|
scope: z.ZodOptional<z.ZodObject<{
|
|
1036
1070
|
surface: z.ZodOptional<z.ZodString>;
|
|
1037
1071
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -1141,6 +1175,9 @@ export declare const EvidencePageSchema: z.ZodObject<{
|
|
|
1141
1175
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1142
1176
|
recording: z.ZodOptional<z.ZodString>;
|
|
1143
1177
|
available: z.ZodBoolean;
|
|
1178
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
1179
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
1180
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
1144
1181
|
scope: z.ZodOptional<z.ZodObject<{
|
|
1145
1182
|
surface: z.ZodOptional<z.ZodString>;
|
|
1146
1183
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -1721,6 +1758,9 @@ export declare const ReviewSnapshotSchema: z.ZodObject<{
|
|
|
1721
1758
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1722
1759
|
recording: z.ZodOptional<z.ZodString>;
|
|
1723
1760
|
available: z.ZodBoolean;
|
|
1761
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
1762
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
1763
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
1724
1764
|
scope: z.ZodOptional<z.ZodObject<{
|
|
1725
1765
|
surface: z.ZodOptional<z.ZodString>;
|
|
1726
1766
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -1784,6 +1824,9 @@ export declare const ReviewEntrySchema: z.ZodObject<{
|
|
|
1784
1824
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1785
1825
|
recording: z.ZodOptional<z.ZodString>;
|
|
1786
1826
|
available: z.ZodBoolean;
|
|
1827
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
1828
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
1829
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
1787
1830
|
scope: z.ZodOptional<z.ZodObject<{
|
|
1788
1831
|
surface: z.ZodOptional<z.ZodString>;
|
|
1789
1832
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -1866,6 +1909,9 @@ export declare const ReviewCollectionSchema: z.ZodObject<{
|
|
|
1866
1909
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1867
1910
|
recording: z.ZodOptional<z.ZodString>;
|
|
1868
1911
|
available: z.ZodBoolean;
|
|
1912
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
1913
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
1914
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
1869
1915
|
scope: z.ZodOptional<z.ZodObject<{
|
|
1870
1916
|
surface: z.ZodOptional<z.ZodString>;
|
|
1871
1917
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -2025,6 +2071,9 @@ export declare const ReviewCollectionDetailSchema: z.ZodObject<{
|
|
|
2025
2071
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2026
2072
|
recording: z.ZodOptional<z.ZodString>;
|
|
2027
2073
|
available: z.ZodBoolean;
|
|
2074
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
2075
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
2076
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
2028
2077
|
scope: z.ZodOptional<z.ZodObject<{
|
|
2029
2078
|
surface: z.ZodOptional<z.ZodString>;
|
|
2030
2079
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -2156,6 +2205,9 @@ export declare const ReviewManifestSchema: z.ZodObject<{
|
|
|
2156
2205
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2157
2206
|
recording: z.ZodOptional<z.ZodString>;
|
|
2158
2207
|
available: z.ZodBoolean;
|
|
2208
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
2209
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
2210
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
2159
2211
|
scope: z.ZodOptional<z.ZodObject<{
|
|
2160
2212
|
surface: z.ZodOptional<z.ZodString>;
|
|
2161
2213
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -2284,6 +2336,9 @@ export declare const TestResultEntrySchema: z.ZodObject<{
|
|
|
2284
2336
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2285
2337
|
recording: z.ZodOptional<z.ZodString>;
|
|
2286
2338
|
available: z.ZodBoolean;
|
|
2339
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
2340
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
2341
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
2287
2342
|
scope: z.ZodOptional<z.ZodObject<{
|
|
2288
2343
|
surface: z.ZodOptional<z.ZodString>;
|
|
2289
2344
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -2394,6 +2449,9 @@ export declare const TestSummarySchema: z.ZodObject<{
|
|
|
2394
2449
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2395
2450
|
recording: z.ZodOptional<z.ZodString>;
|
|
2396
2451
|
available: z.ZodBoolean;
|
|
2452
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
2453
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
2454
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
2397
2455
|
scope: z.ZodOptional<z.ZodObject<{
|
|
2398
2456
|
surface: z.ZodOptional<z.ZodString>;
|
|
2399
2457
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -2700,6 +2758,9 @@ export declare const TestCatalogSchema: z.ZodObject<{
|
|
|
2700
2758
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2701
2759
|
recording: z.ZodOptional<z.ZodString>;
|
|
2702
2760
|
available: z.ZodBoolean;
|
|
2761
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
2762
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
2763
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
2703
2764
|
scope: z.ZodOptional<z.ZodObject<{
|
|
2704
2765
|
surface: z.ZodOptional<z.ZodString>;
|
|
2705
2766
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -2938,6 +2999,9 @@ export declare const TestHistorySchema: z.ZodObject<{
|
|
|
2938
2999
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2939
3000
|
recording: z.ZodOptional<z.ZodString>;
|
|
2940
3001
|
available: z.ZodBoolean;
|
|
3002
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
3003
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
3004
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
2941
3005
|
scope: z.ZodOptional<z.ZodObject<{
|
|
2942
3006
|
surface: z.ZodOptional<z.ZodString>;
|
|
2943
3007
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -3066,6 +3130,9 @@ export declare const TestHistorySchema: z.ZodObject<{
|
|
|
3066
3130
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3067
3131
|
recording: z.ZodOptional<z.ZodString>;
|
|
3068
3132
|
available: z.ZodBoolean;
|
|
3133
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
3134
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
3135
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
3069
3136
|
scope: z.ZodOptional<z.ZodObject<{
|
|
3070
3137
|
surface: z.ZodOptional<z.ZodString>;
|
|
3071
3138
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -3267,6 +3334,21 @@ export declare const ReportRunSchema: z.ZodObject<{
|
|
|
3267
3334
|
references: z.ZodNumber;
|
|
3268
3335
|
recordings: z.ZodNumber;
|
|
3269
3336
|
unavailable: z.ZodNumber;
|
|
3337
|
+
missing: z.ZodOptional<z.ZodNumber>;
|
|
3338
|
+
}, z.core.$loose>>;
|
|
3339
|
+
recordings: z.ZodOptional<z.ZodObject<{
|
|
3340
|
+
state: z.ZodEnum<{
|
|
3341
|
+
unknown: "unknown";
|
|
3342
|
+
complete: "complete";
|
|
3343
|
+
incomplete: "incomplete";
|
|
3344
|
+
"none-expected": "none-expected";
|
|
3345
|
+
}>;
|
|
3346
|
+
expected: z.ZodNumber;
|
|
3347
|
+
published: z.ZodNumber;
|
|
3348
|
+
skipped: z.ZodNumber;
|
|
3349
|
+
unresolved: z.ZodNumber;
|
|
3350
|
+
notApplicable: z.ZodNumber;
|
|
3351
|
+
layersWithoutReceipt: z.ZodNumber;
|
|
3270
3352
|
}, z.core.$loose>>;
|
|
3271
3353
|
attachments: z.ZodOptional<z.ZodNumber>;
|
|
3272
3354
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -3313,6 +3395,10 @@ export declare const QueryFacetsSchema: z.ZodObject<{
|
|
|
3313
3395
|
value: z.ZodString;
|
|
3314
3396
|
count: z.ZodNumber;
|
|
3315
3397
|
}, z.core.$loose>>>;
|
|
3398
|
+
recordings: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
3399
|
+
value: z.ZodString;
|
|
3400
|
+
count: z.ZodNumber;
|
|
3401
|
+
}, z.core.$loose>>>;
|
|
3316
3402
|
}, z.core.$loose>;
|
|
3317
3403
|
/** `GET /api/reports/runs`: runs, newest first. */
|
|
3318
3404
|
export declare const RunListSchema: z.ZodObject<{
|
|
@@ -3354,6 +3440,21 @@ export declare const RunListSchema: z.ZodObject<{
|
|
|
3354
3440
|
references: z.ZodNumber;
|
|
3355
3441
|
recordings: z.ZodNumber;
|
|
3356
3442
|
unavailable: z.ZodNumber;
|
|
3443
|
+
missing: z.ZodOptional<z.ZodNumber>;
|
|
3444
|
+
}, z.core.$loose>>;
|
|
3445
|
+
recordings: z.ZodOptional<z.ZodObject<{
|
|
3446
|
+
state: z.ZodEnum<{
|
|
3447
|
+
unknown: "unknown";
|
|
3448
|
+
complete: "complete";
|
|
3449
|
+
incomplete: "incomplete";
|
|
3450
|
+
"none-expected": "none-expected";
|
|
3451
|
+
}>;
|
|
3452
|
+
expected: z.ZodNumber;
|
|
3453
|
+
published: z.ZodNumber;
|
|
3454
|
+
skipped: z.ZodNumber;
|
|
3455
|
+
unresolved: z.ZodNumber;
|
|
3456
|
+
notApplicable: z.ZodNumber;
|
|
3457
|
+
layersWithoutReceipt: z.ZodNumber;
|
|
3357
3458
|
}, z.core.$loose>>;
|
|
3358
3459
|
attachments: z.ZodOptional<z.ZodNumber>;
|
|
3359
3460
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -3396,6 +3497,10 @@ export declare const RunListSchema: z.ZodObject<{
|
|
|
3396
3497
|
value: z.ZodString;
|
|
3397
3498
|
count: z.ZodNumber;
|
|
3398
3499
|
}, z.core.$loose>>>;
|
|
3500
|
+
recordings: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
3501
|
+
value: z.ZodString;
|
|
3502
|
+
count: z.ZodNumber;
|
|
3503
|
+
}, z.core.$loose>>>;
|
|
3399
3504
|
}, z.core.$loose>>;
|
|
3400
3505
|
}, z.core.$loose>;
|
|
3401
3506
|
/** One recorded result that carries evidence: where and when it was recorded and what it carries. */
|
|
@@ -3435,6 +3540,9 @@ export declare const ArtifactResultSchema: z.ZodObject<{
|
|
|
3435
3540
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3436
3541
|
recording: z.ZodOptional<z.ZodString>;
|
|
3437
3542
|
available: z.ZodBoolean;
|
|
3543
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
3544
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
3545
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
3438
3546
|
scope: z.ZodOptional<z.ZodObject<{
|
|
3439
3547
|
surface: z.ZodOptional<z.ZodString>;
|
|
3440
3548
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -3505,6 +3613,9 @@ export declare const ArtifactListSchema: z.ZodObject<{
|
|
|
3505
3613
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3506
3614
|
recording: z.ZodOptional<z.ZodString>;
|
|
3507
3615
|
available: z.ZodBoolean;
|
|
3616
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
3617
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
3618
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
3508
3619
|
scope: z.ZodOptional<z.ZodObject<{
|
|
3509
3620
|
surface: z.ZodOptional<z.ZodString>;
|
|
3510
3621
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -3566,6 +3677,10 @@ export declare const ArtifactListSchema: z.ZodObject<{
|
|
|
3566
3677
|
value: z.ZodString;
|
|
3567
3678
|
count: z.ZodNumber;
|
|
3568
3679
|
}, z.core.$loose>>>;
|
|
3680
|
+
recordings: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
3681
|
+
value: z.ZodString;
|
|
3682
|
+
count: z.ZodNumber;
|
|
3683
|
+
}, z.core.$loose>>>;
|
|
3569
3684
|
}, z.core.$loose>;
|
|
3570
3685
|
}, z.core.$loose>;
|
|
3571
3686
|
/** `GET /api/reports/runs/detail`: one run and its last result for every test, environment and producer it recorded. */
|
|
@@ -3607,6 +3722,21 @@ export declare const RunDetailSchema: z.ZodObject<{
|
|
|
3607
3722
|
references: z.ZodNumber;
|
|
3608
3723
|
recordings: z.ZodNumber;
|
|
3609
3724
|
unavailable: z.ZodNumber;
|
|
3725
|
+
missing: z.ZodOptional<z.ZodNumber>;
|
|
3726
|
+
}, z.core.$loose>>;
|
|
3727
|
+
recordings: z.ZodOptional<z.ZodObject<{
|
|
3728
|
+
state: z.ZodEnum<{
|
|
3729
|
+
unknown: "unknown";
|
|
3730
|
+
complete: "complete";
|
|
3731
|
+
incomplete: "incomplete";
|
|
3732
|
+
"none-expected": "none-expected";
|
|
3733
|
+
}>;
|
|
3734
|
+
expected: z.ZodNumber;
|
|
3735
|
+
published: z.ZodNumber;
|
|
3736
|
+
skipped: z.ZodNumber;
|
|
3737
|
+
unresolved: z.ZodNumber;
|
|
3738
|
+
notApplicable: z.ZodNumber;
|
|
3739
|
+
layersWithoutReceipt: z.ZodNumber;
|
|
3610
3740
|
}, z.core.$loose>>;
|
|
3611
3741
|
attachments: z.ZodOptional<z.ZodNumber>;
|
|
3612
3742
|
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -3639,6 +3769,9 @@ export declare const RunDetailSchema: z.ZodObject<{
|
|
|
3639
3769
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3640
3770
|
recording: z.ZodOptional<z.ZodString>;
|
|
3641
3771
|
available: z.ZodBoolean;
|
|
3772
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
3773
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
3774
|
+
poster: z.ZodOptional<z.ZodString>;
|
|
3642
3775
|
scope: z.ZodOptional<z.ZodObject<{
|
|
3643
3776
|
surface: z.ZodOptional<z.ZodString>;
|
|
3644
3777
|
deviceKind: z.ZodOptional<z.ZodString>;
|
|
@@ -3676,6 +3809,7 @@ export declare const RunDetailSchema: z.ZodObject<{
|
|
|
3676
3809
|
references: z.ZodNumber;
|
|
3677
3810
|
recordings: z.ZodNumber;
|
|
3678
3811
|
unavailable: z.ZodNumber;
|
|
3812
|
+
missing: z.ZodOptional<z.ZodNumber>;
|
|
3679
3813
|
}, z.core.$loose>>;
|
|
3680
3814
|
}, z.core.$loose>>>;
|
|
3681
3815
|
}, z.core.$loose>;
|
package/dist/schema/src/api.js
CHANGED
|
@@ -71,13 +71,17 @@ 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'),
|
|
75
|
+
durationMs: z.number().nonnegative().optional().describe('How long the recording is, in milliseconds, as its producer declared it: a hint to show before the file is opened, never a latency. Absent when none was declared, and in documents of older servers'),
|
|
76
|
+
poster: z.string().optional().describe('The bundle key, in the same layer, of the image the producer named as this recording\'s poster: a hint to show before the file is opened. Absent when there is none or the layer\'s bundle does not hold it, and in documents of older servers'),
|
|
74
77
|
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
78
|
});
|
|
76
79
|
/** Video references as counts: how many are referenced, how many distinct recordings can be played, how many cannot. */
|
|
77
80
|
export const VideoCountsSchema = z.looseObject({
|
|
78
81
|
references: z.number().int().nonnegative().describe('Every reference to a video; identical bytes referenced twice count twice'),
|
|
79
82
|
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')
|
|
83
|
+
unavailable: z.number().int().nonnegative().describe('References that name no bytes, or bytes the layer does not hold'),
|
|
84
|
+
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
85
|
});
|
|
82
86
|
/** What a result carries beyond its outcome, as counts and short facts. Present only when there is something. */
|
|
83
87
|
export const EvidenceSummarySchema = z.looseObject({
|
|
@@ -625,6 +629,12 @@ export const ReportRunSchema = z.looseObject({
|
|
|
625
629
|
totalDurationMs: z.number().nullable(),
|
|
626
630
|
failing: z.array(z.looseObject({ key: z.string(), title: z.string(), environment: z.string().nullable(), detail: z.string() })),
|
|
627
631
|
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'),
|
|
632
|
+
recordings: z.looseObject({
|
|
633
|
+
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'),
|
|
634
|
+
expected: z.number().int().nonnegative(), published: z.number().int().nonnegative().describe('Of the expected recordings, uploaded or referenced by address'),
|
|
635
|
+
skipped: z.number().int().nonnegative(), unresolved: z.number().int().nonnegative(), notApplicable: z.number().int().nonnegative(),
|
|
636
|
+
layersWithoutReceipt: z.number().int().nonnegative().describe('Layers of the run that declared no recording expectations: nothing is claimed for them')
|
|
637
|
+
}).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
638
|
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
639
|
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
640
|
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 +647,8 @@ export const QueryFacetValueSchema = z.looseObject({ value: z.string(), count: z
|
|
|
637
647
|
export const QueryFacetsSchema = z.looseObject({
|
|
638
648
|
artifactTags: z.array(QueryFacetValueSchema), types: z.array(QueryFacetValueSchema), labels: z.array(QueryFacetValueSchema).describe('Values are `key=value`'),
|
|
639
649
|
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')
|
|
650
|
+
domains: z.array(QueryFacetValueSchema).optional().describe('Only for artifacts: runs have no domain'),
|
|
651
|
+
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
652
|
});
|
|
642
653
|
/** `GET /api/reports/runs`: runs, newest first. */
|
|
643
654
|
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
|
|