@crvouga/atlas 1.16.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 +13 -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 +20 -1
- package/dist/reports/src/test-catalog.js +31 -9
- package/dist/schema/src/api.d.ts +113 -0
- package/dist/schema/src/api.js +17 -3
- 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/extending.md +1 -1
- package/docs/reference/cli.md +11 -2
- package/docs/reference/http-api.md +2 -0
- package/docs/reference/reports.md +202 -9
- package/docs/reference/schema.md +19 -1
- package/docs/rich-evidence.md +32 -5
- package/docs/server.md +1 -1
- package/docs/ui.md +8 -0
- package/llms-full.txt +56 -9
- 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 +30 -0
- package/packages/schema/schemas/test-history.schema.json +48 -0
- package/packages/schema/schemas/verify-recordings-result.schema.json +97 -0
- package/packages/server/openapi.json +318 -0
- package/packages/visualizer/src/evidence/applicability-view.tsx +46 -20
- package/packages/visualizer/src/evidence/applicability.test.ts +68 -1
- package/packages/visualizer/src/evidence/applicability.ts +121 -26
- package/packages/visualizer/src/explorer/ArtifactsView.tsx +3 -2
- package/packages/visualizer/src/explorer/Explorer.tsx +96 -8
- package/packages/visualizer/src/explorer/RunsView.tsx +28 -3
- package/packages/visualizer/src/explorer/TestDetail.tsx +14 -1
- package/packages/visualizer/src/explorer/applicability.ts +43 -0
- package/packages/visualizer/src/explorer/filters.tsx +11 -3
- package/packages/visualizer/src/explorer/search.ts +20 -6
package/llms-full.txt
CHANGED
|
@@ -172,6 +172,7 @@ JSON Schema (`@crvouga/atlas/schemas/<name>.schema.json`, draft 2020-12):
|
|
|
172
172
|
| `atlas report merge` | `merge-result` |
|
|
173
173
|
| `atlas report doctor` | `doctor-result` |
|
|
174
174
|
| `atlas report status` | `report-status` |
|
|
175
|
+
| `atlas report verify-recordings` | `verify-recordings-result` |
|
|
175
176
|
| `a command that was wrong (standard error)` | `command-error` |
|
|
176
177
|
<!-- /generated:json-command-schemas -->
|
|
177
178
|
|
|
@@ -1196,7 +1197,8 @@ curl "$ATLAS_SERVER_URL/api/reports/artifacts?artifactTag=demo&type=video&domain
|
|
|
1196
1197
|
- **Dimensions.** `artifactTag`, `type` (the media type as a role: `video`, `image`, `audio`, `snapshot`, `text`,
|
|
1197
1198
|
`file`; `video` means a playable recording), `label` (`key=value`, or `key`), `domain` and `spec` (artifacts only),
|
|
1198
1199
|
`environment` (the device or client), `producer`, `branch`, `sha` (seven or more characters), `outcome` (`passed`,
|
|
1199
|
-
`failed`, `running`, `not-run`), `
|
|
1200
|
+
`failed`, `running`, `not-run`), `recordings` (runs only: `complete`, `incomplete`, `none-expected` or `unknown`, see
|
|
1201
|
+
[recording completeness](#recording-completeness)), `since` and `until` (epoch milliseconds or an ISO date), and `q` (words).
|
|
1200
1202
|
- **Semantics.** Filters combine with AND across dimensions and OR within one (`environment=ios,android`). With both
|
|
1201
1203
|
`artifactTag` and `type`, one attachment must be both where the report says which video carries which tag: a tagged
|
|
1202
1204
|
screenshot beside an untagged video is not a tagged video. `inherited=1` also counts the tags an attachment inherits
|
|
@@ -1463,10 +1465,36 @@ publish; it never contains a path or a token.
|
|
|
1463
1465
|
retry (publishing again reuses the stored files).
|
|
1464
1466
|
- `atlas report status --format json` has `recordings`: `state` is `complete`, `incomplete`, `none-expected` or
|
|
1465
1467
|
`unknown`, with counts and each gap. It never changes `ok`. A layer without a receipt is `unknown`, never `complete`.
|
|
1466
|
-
- The viewer shows `Recordings 2 of 3: incomplete` beside the run's origin
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1468
|
+
- The viewer shows `Recordings 2 of 3: incomplete` beside the run's origin and in each row of the Runs tab, apart from
|
|
1469
|
+
its green or red outcomes.
|
|
1470
|
+
- **Find runs by completeness.** `GET /api/reports/runs?recordings=incomplete` (and the Runs tab's *Recordings* filter,
|
|
1471
|
+
`?tab=runs&recordings=incomplete`) keep the runs whose layers have a skipped or unresolved expected recording. The
|
|
1472
|
+
values are `complete`, `incomplete`, `none-expected` and `unknown`, comma-separated for OR, and they combine with the
|
|
1473
|
+
other filters by AND. A run whose layers declared no expectations is `unknown`, never `complete`, and a run with any
|
|
1474
|
+
layer without a receipt cannot be `complete`. It is answered from the layers' receipts, before the page limit, and
|
|
1475
|
+
never reads a recording; the facet counts say how many runs have each state. It is a property of a run, so the
|
|
1476
|
+
artifacts list does not take it. A server that predates it ignores the parameter and does not name it in `filters`, and
|
|
1477
|
+
the viewer then says the list is not narrowed by it.
|
|
1478
|
+
|
|
1479
|
+
### Is the recording still there?
|
|
1480
|
+
|
|
1481
|
+
A receipt says a file was published. Whether it is still retrievable later is a separate question, and Atlas answers it
|
|
1482
|
+
two ways without touching a check's result:
|
|
1483
|
+
|
|
1484
|
+
- **Layer bundle.** A video that names a `bundleKey` the layer's bundle does not list (the file was acknowledged and is
|
|
1485
|
+
gone, or never arrived) is not offered to play. The report marks it `available: false` with `reason: "not-in-bundle"`,
|
|
1486
|
+
the run counts it in `videos.unavailable` and `videos.missing`, and the Runs tab explains that the run stored the file
|
|
1487
|
+
but no longer holds it, which is different from a reference that never named any bytes.
|
|
1488
|
+
- **`atlas report verify-recordings`** reads the videos of the stored layers back and checks, for each, that the bundle
|
|
1489
|
+
lists it, that its blob is still in the store, that its size and SHA-256 are the recorded ones, and that it begins like
|
|
1490
|
+
the container its media type names (WebM, MP4, QuickTime, Ogg, AVI). It exits 1 and names the layer and check for
|
|
1491
|
+
every gap (`not-in-bundle`, `blob-missing`, `unreadable`, `size-mismatch`, `checksum-mismatch`, `undecodable`);
|
|
1492
|
+
`--format json` prints the `verify-recordings-result` document. `--layer <id>` and `--limit <n>` narrow the work, since
|
|
1493
|
+
it reads blobs. A store that cannot answer is `unreadable`, never verified. Test results are unchanged either way.
|
|
1494
|
+
|
|
1495
|
+
Both are statements about stored bytes. Atlas does not check that a stored video plays in a given browser (a valid header
|
|
1496
|
+
can still have an unsupported codec or be truncated), and acknowledging an upload is not playback. Videos given only by
|
|
1497
|
+
`uri` are counted as referenced and not checked.
|
|
1470
1498
|
</doc>
|
|
1471
1499
|
|
|
1472
1500
|
<doc path="docs/ui-catalog.md">
|
|
@@ -2058,7 +2086,7 @@ with `format=markdown` (or `Accept: text/markdown`), and takes the project prefi
|
|
|
2058
2086
|
| One test: every recorded result (status, duration, environment, branch, commit, CI run), newest first | `GET /api/reports/tests/history?key=<key>` |
|
|
2059
2087
|
| How reliable one test is in a scope (environment, producer, parameters, branch, commit, spec revision, time window): independent executions, first-try and eventual success, what was left out and why | `GET /api/reports/tests/reliability?key=<key>&environment=phone` |
|
|
2060
2088
|
| Why Specs, domains and counts disagree: ambiguous spec paths, shared domains, gaps, a reconciliation of the totals | `GET /api/reports/tests/health` |
|
|
2061
|
-
| The runs that recorded the report (by CI run URL, else branch and commit); `?video=true` keeps those with a playable video; `artifactTag`, `type`, `label`, `environment`, `branch`, `outcome`, `since`, `until` narrow it ([filtering](rich-evidence.md#finding-runs-and-artifacts)) | `GET /api/reports/runs` |
|
|
2089
|
+
| The runs that recorded the report (by CI run URL, else branch and commit); `?video=true` keeps those with a playable video; `artifactTag`, `type`, `label`, `environment`, `branch`, `outcome`, `recordings` (completeness of the recordings the run's layers expected), `since`, `until` narrow it ([filtering](rich-evidence.md#finding-runs-and-artifacts)) | `GET /api/reports/runs` |
|
|
2062
2090
|
| Recorded results that carry evidence, across the whole history, found by tag, media type, label, feature, environment, branch, revision, outcome and time | `GET /api/reports/artifacts?artifactTag=demo&type=video` |
|
|
2063
2091
|
| Every test one run recorded | `GET /api/reports/runs/detail?key=<run key>` |
|
|
2064
2092
|
|
|
@@ -3204,7 +3232,7 @@ carry any of these. Every one is optional.
|
|
|
3204
3232
|
| `annotations[]` | Notes about the result: a warning, a deprecation, an accessibility finding, a coverage figure. |
|
|
3205
3233
|
| `attempts[]` | Every try, when the check was retried. |
|
|
3206
3234
|
| `tags[]` | Free labels to filter by: `smoke`, `payments`. |
|
|
3207
|
-
| `labels{}` | Facts about the result that are not its identity: `owner`, `severity`, `browser`, `build`. The viewer reads `build`, `platform`, `applies-to` and `applies-to-by` to tell whether evidence applies to a release (see [the viewer conventions](ui.md#behaviors-read-watch-inspect)). `behavior-id` and `example-id` declare a stable id for the behavior and for one example of an outline, and `outline` names the outline; the [catalog health](server.md#reading-the-report-as-an-agent) report counts them and names an id shared by several checks. They never change which check a result belongs to. |
|
|
3235
|
+
| `labels{}` | Facts about the result that are not its identity: `owner`, `severity`, `browser`, `build`. The viewer reads `build`, `platform`, `applies-to` and `applies-to-by` to tell whether evidence applies to a release, and `published-at` and `enriched-at` (epoch milliseconds or an ISO date) to show when it was published or enriched apart from when the checks ran (see [the viewer conventions](ui.md#behaviors-read-watch-inspect)). `behavior-id` and `example-id` declare a stable id for the behavior and for one example of an outline, and `outline` names the outline; the [catalog health](server.md#reading-the-report-as-an-agent) report counts them and names an id shared by several checks. They never change which check a result belongs to. |
|
|
3208
3236
|
| `scope{}` | What the evidence does and does not show: surface, device kind, synthetic data, scripted dependencies, audio, pacing, what was asserted and its limits. Unknown when absent. See [Evidence scope](rich-evidence.md#evidence-scope). |
|
|
3209
3237
|
| `links[]` | Where to read more: the CI run, the issue, the trace client. |
|
|
3210
3238
|
| `extensions{}` | Structured data of your own or a tool's, under a name you own. |
|
|
@@ -4519,6 +4547,14 @@ when Watch is on screen.
|
|
|
4519
4547
|
what they know with labels: `build`, `platform`, and `applies-to` with `applies-to-by` (the policy that asserts the
|
|
4520
4548
|
evidence still holds for those builds; without it the assertion is refused). The "Stale or unverified" filter
|
|
4521
4549
|
(`evidence=stale`) lists every behavior whose evidence does not apply, including those with none.
|
|
4550
|
+
- The test explorer makes the same reading of every test from the catalog (`explorer/applicability.ts`): the catalog
|
|
4551
|
+
carries the spec's fingerprint now (`spec.fingerprint`) and, on each current result, `specRevision`, `freshness` and
|
|
4552
|
+
`provenance` (the labels above), all optional. The same address names (`release`, `releaseSha`, `releasePlatform`,
|
|
4553
|
+
`evidence=stale`) give the "Stale or unverified" button, the "Stale evidence first" sort, a verdict badge on rows
|
|
4554
|
+
(stale always; unknown or none when a release is named or evidence is filtered or sorted), and the summary in test
|
|
4555
|
+
detail. Layers carry no publication time, because a layer's id is the digest of its content and a time of upload in
|
|
4556
|
+
it would make a retried publish a different layer: a producer that knows states `published-at` and `enriched-at`
|
|
4557
|
+
labels, shown apart from "Checks ran", which alone is the age.
|
|
4522
4558
|
- A recording is always labelled illustrative: it shows one run and does not approve a behavior for production.
|
|
4523
4559
|
`demo`/`representative` tags only add a "Representative demo" label.
|
|
4524
4560
|
- The spec index searches titles, paths and declared domains, and can group by the domain from spec metadata (specs with
|
|
@@ -5244,6 +5280,8 @@ atlas report — layered evidence for any kind of spec
|
|
|
5244
5280
|
[--specs <dir>] [--format text|json|markdown]
|
|
5245
5281
|
[--require-environments a,b] [--require-all-specs]
|
|
5246
5282
|
[--branch <name>]... [--ignore-modified]
|
|
5283
|
+
atlas report verify-recordings [--store <dir|s3://…|id=url>]... [--backends <module>] [--layer <id>]...
|
|
5284
|
+
[--limit <n>] [--branch <name>]... [--ignore-modified] [--format text|json]
|
|
5247
5285
|
atlas report merge [--store …]... [--backends <module>] --into <dir|s3://…>
|
|
5248
5286
|
atlas report doctor [--store …]... [--role publisher|reader|both]
|
|
5249
5287
|
atlas report policy --store s3://bucket/prefix [--role publisher|reader|both]
|
|
@@ -5287,6 +5325,13 @@ atlas report — layered evidence for any kind of spec
|
|
|
5287
5325
|
--require-all-specs fail while any spec has no results
|
|
5288
5326
|
--branch <name> only layers recorded on this branch (repeatable)
|
|
5289
5327
|
--ignore-modified leave out layers from modified checkouts and unknown origins
|
|
5328
|
+
verify-recordings Read back the videos the layers published and check they are still there as published: the
|
|
5329
|
+
layer still lists the file, its blob is still stored, its size and SHA-256 are the recorded ones, and it
|
|
5330
|
+
begins like the container its media type names. Exit 1 when any video is missing, unreadable, corrupt or
|
|
5331
|
+
not that container, naming the layer and check; test results are never changed. This checks stored bytes,
|
|
5332
|
+
not playback in a browser. Videos given only by address are counted, not checked.
|
|
5333
|
+
--layer <id> only the layer whose id starts with this (repeatable; at least 7 digits)
|
|
5334
|
+
--limit <n> only the newest n layers
|
|
5290
5335
|
merge Copy the layers of several stores into one.
|
|
5291
5336
|
doctor Check that a store works: credentials, listing, writing, and what it holds.
|
|
5292
5337
|
policy Print the least-privilege IAM policy for publishers, readers, or both.
|
|
@@ -5295,8 +5340,8 @@ atlas report — layered evidence for any kind of spec
|
|
|
5295
5340
|
{ id, label?, store } (or a function returning it): a device lab, anything
|
|
5296
5341
|
that implements ObjectStore.
|
|
5297
5342
|
|
|
5298
|
-
--format json (alias --json) publish, stream, merge, doctor and
|
|
5299
|
-
(schemas: publish-result, stream-result, merge-result, doctor-result, report-status). A command
|
|
5343
|
+
--format json (alias --json) publish, stream, merge, doctor, status and verify-recordings print one JSON document instead of prose
|
|
5344
|
+
(schemas: publish-result, stream-result, merge-result, doctor-result, report-status, verify-recordings-result). A command
|
|
5300
5345
|
that is wrong is {"ok":false,"error":{"message":…,"code":"usage"}} on standard error.
|
|
5301
5346
|
A store may be an Atlas server (https://…): ATLAS_STORE=https://atlas.example.com, with ATLAS_TOKEN.
|
|
5302
5347
|
|
|
@@ -6140,6 +6185,7 @@ Every run, newest first: layers grouped by their CI run URL (else branch and com
|
|
|
6140
6185
|
- `branch` (query): Branches.
|
|
6141
6186
|
- `sha` (query): Revisions: a full commit id or a prefix of at least seven characters.
|
|
6142
6187
|
- `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`.
|
|
6188
|
+
- `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`.
|
|
6143
6189
|
- `q` (query): Words that must all appear in the title, id, spec, branch, producer, environment, tags or labels.
|
|
6144
6190
|
- `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.
|
|
6145
6191
|
- `until` (query): Only records at or before this time (same forms as `since`).
|
|
@@ -6168,6 +6214,7 @@ Scoped to one project. The same project may be selected on the unprefixed API us
|
|
|
6168
6214
|
- `branch` (query): Branches.
|
|
6169
6215
|
- `sha` (query): Revisions: a full commit id or a prefix of at least seven characters.
|
|
6170
6216
|
- `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`.
|
|
6217
|
+
- `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`.
|
|
6171
6218
|
- `q` (query): Words that must all appear in the title, id, spec, branch, producer, environment, tags or labels.
|
|
6172
6219
|
- `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.
|
|
6173
6220
|
- `until` (query): Only records at or before this time (same forms as `since`).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crvouga/atlas",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"description": "Atlas: specs of any kind, reported as layered evidence. Publish checks from any runner (JUnit, CTRF, a script), combine them across nodes, branches, environments and backends, gate CI on the result, and run statecharts against the real app.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -264,6 +264,10 @@
|
|
|
264
264
|
"type": "boolean",
|
|
265
265
|
"description": "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"
|
|
266
266
|
},
|
|
267
|
+
"reason": {
|
|
268
|
+
"description": "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",
|
|
269
|
+
"type": "string"
|
|
270
|
+
},
|
|
267
271
|
"scope": {
|
|
268
272
|
"description": "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",
|
|
269
273
|
"type": "object",
|
|
@@ -743,6 +747,10 @@
|
|
|
743
747
|
"type": "boolean",
|
|
744
748
|
"description": "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"
|
|
745
749
|
},
|
|
750
|
+
"reason": {
|
|
751
|
+
"description": "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",
|
|
752
|
+
"type": "string"
|
|
753
|
+
},
|
|
746
754
|
"scope": {
|
|
747
755
|
"description": "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",
|
|
748
756
|
"type": "object",
|
|
@@ -264,6 +264,10 @@
|
|
|
264
264
|
"type": "boolean",
|
|
265
265
|
"description": "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"
|
|
266
266
|
},
|
|
267
|
+
"reason": {
|
|
268
|
+
"description": "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",
|
|
269
|
+
"type": "string"
|
|
270
|
+
},
|
|
267
271
|
"scope": {
|
|
268
272
|
"description": "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",
|
|
269
273
|
"type": "object",
|
|
@@ -743,6 +747,10 @@
|
|
|
743
747
|
"type": "boolean",
|
|
744
748
|
"description": "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"
|
|
745
749
|
},
|
|
750
|
+
"reason": {
|
|
751
|
+
"description": "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",
|
|
752
|
+
"type": "string"
|
|
753
|
+
},
|
|
746
754
|
"scope": {
|
|
747
755
|
"description": "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",
|
|
748
756
|
"type": "object",
|
|
@@ -251,6 +251,10 @@
|
|
|
251
251
|
"type": "boolean",
|
|
252
252
|
"description": "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"
|
|
253
253
|
},
|
|
254
|
+
"reason": {
|
|
255
|
+
"description": "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",
|
|
256
|
+
"type": "string"
|
|
257
|
+
},
|
|
254
258
|
"scope": {
|
|
255
259
|
"description": "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",
|
|
256
260
|
"type": "object",
|
|
@@ -255,6 +255,10 @@
|
|
|
255
255
|
"type": "boolean",
|
|
256
256
|
"description": "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"
|
|
257
257
|
},
|
|
258
|
+
"reason": {
|
|
259
|
+
"description": "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",
|
|
260
|
+
"type": "string"
|
|
261
|
+
},
|
|
258
262
|
"scope": {
|
|
259
263
|
"description": "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",
|
|
260
264
|
"type": "object",
|
|
@@ -162,6 +162,12 @@
|
|
|
162
162
|
"minimum": 0,
|
|
163
163
|
"maximum": 9007199254740991,
|
|
164
164
|
"description": "References that name no bytes, or bytes the layer does not hold"
|
|
165
|
+
},
|
|
166
|
+
"missing": {
|
|
167
|
+
"description": "Of `unavailable`, those that name a file the layer's bundle does not hold (stored, then gone). Absent when there are none",
|
|
168
|
+
"type": "integer",
|
|
169
|
+
"exclusiveMinimum": 0,
|
|
170
|
+
"maximum": 9007199254740991
|
|
165
171
|
}
|
|
166
172
|
},
|
|
167
173
|
"required": [
|
|
@@ -171,6 +177,64 @@
|
|
|
171
177
|
],
|
|
172
178
|
"additionalProperties": {}
|
|
173
179
|
},
|
|
180
|
+
"recordings": {
|
|
181
|
+
"description": "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",
|
|
182
|
+
"type": "object",
|
|
183
|
+
"properties": {
|
|
184
|
+
"state": {
|
|
185
|
+
"type": "string",
|
|
186
|
+
"enum": [
|
|
187
|
+
"complete",
|
|
188
|
+
"incomplete",
|
|
189
|
+
"none-expected",
|
|
190
|
+
"unknown"
|
|
191
|
+
],
|
|
192
|
+
"description": "`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"
|
|
193
|
+
},
|
|
194
|
+
"expected": {
|
|
195
|
+
"type": "integer",
|
|
196
|
+
"minimum": 0,
|
|
197
|
+
"maximum": 9007199254740991
|
|
198
|
+
},
|
|
199
|
+
"published": {
|
|
200
|
+
"type": "integer",
|
|
201
|
+
"minimum": 0,
|
|
202
|
+
"maximum": 9007199254740991,
|
|
203
|
+
"description": "Of the expected recordings, uploaded or referenced by address"
|
|
204
|
+
},
|
|
205
|
+
"skipped": {
|
|
206
|
+
"type": "integer",
|
|
207
|
+
"minimum": 0,
|
|
208
|
+
"maximum": 9007199254740991
|
|
209
|
+
},
|
|
210
|
+
"unresolved": {
|
|
211
|
+
"type": "integer",
|
|
212
|
+
"minimum": 0,
|
|
213
|
+
"maximum": 9007199254740991
|
|
214
|
+
},
|
|
215
|
+
"notApplicable": {
|
|
216
|
+
"type": "integer",
|
|
217
|
+
"minimum": 0,
|
|
218
|
+
"maximum": 9007199254740991
|
|
219
|
+
},
|
|
220
|
+
"layersWithoutReceipt": {
|
|
221
|
+
"type": "integer",
|
|
222
|
+
"minimum": 0,
|
|
223
|
+
"maximum": 9007199254740991,
|
|
224
|
+
"description": "Layers of the run that declared no recording expectations: nothing is claimed for them"
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
"required": [
|
|
228
|
+
"state",
|
|
229
|
+
"expected",
|
|
230
|
+
"published",
|
|
231
|
+
"skipped",
|
|
232
|
+
"unresolved",
|
|
233
|
+
"notApplicable",
|
|
234
|
+
"layersWithoutReceipt"
|
|
235
|
+
],
|
|
236
|
+
"additionalProperties": {}
|
|
237
|
+
},
|
|
174
238
|
"attachments": {
|
|
175
239
|
"description": "Files attached to the run itself, in its layers, not to a check. Absent when there are none",
|
|
176
240
|
"type": "integer",
|
|
@@ -316,6 +380,10 @@
|
|
|
316
380
|
"type": "boolean",
|
|
317
381
|
"description": "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"
|
|
318
382
|
},
|
|
383
|
+
"reason": {
|
|
384
|
+
"description": "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",
|
|
385
|
+
"type": "string"
|
|
386
|
+
},
|
|
319
387
|
"scope": {
|
|
320
388
|
"description": "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",
|
|
321
389
|
"type": "object",
|
|
@@ -517,6 +585,12 @@
|
|
|
517
585
|
"minimum": 0,
|
|
518
586
|
"maximum": 9007199254740991,
|
|
519
587
|
"description": "References that name no bytes, or bytes the layer does not hold"
|
|
588
|
+
},
|
|
589
|
+
"missing": {
|
|
590
|
+
"description": "Of `unavailable`, those that name a file the layer's bundle does not hold (stored, then gone). Absent when there are none",
|
|
591
|
+
"type": "integer",
|
|
592
|
+
"exclusiveMinimum": 0,
|
|
593
|
+
"maximum": 9007199254740991
|
|
520
594
|
}
|
|
521
595
|
},
|
|
522
596
|
"required": [
|
|
@@ -170,6 +170,12 @@
|
|
|
170
170
|
"minimum": 0,
|
|
171
171
|
"maximum": 9007199254740991,
|
|
172
172
|
"description": "References that name no bytes, or bytes the layer does not hold"
|
|
173
|
+
},
|
|
174
|
+
"missing": {
|
|
175
|
+
"description": "Of `unavailable`, those that name a file the layer's bundle does not hold (stored, then gone). Absent when there are none",
|
|
176
|
+
"type": "integer",
|
|
177
|
+
"exclusiveMinimum": 0,
|
|
178
|
+
"maximum": 9007199254740991
|
|
173
179
|
}
|
|
174
180
|
},
|
|
175
181
|
"required": [
|
|
@@ -179,6 +185,64 @@
|
|
|
179
185
|
],
|
|
180
186
|
"additionalProperties": {}
|
|
181
187
|
},
|
|
188
|
+
"recordings": {
|
|
189
|
+
"description": "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",
|
|
190
|
+
"type": "object",
|
|
191
|
+
"properties": {
|
|
192
|
+
"state": {
|
|
193
|
+
"type": "string",
|
|
194
|
+
"enum": [
|
|
195
|
+
"complete",
|
|
196
|
+
"incomplete",
|
|
197
|
+
"none-expected",
|
|
198
|
+
"unknown"
|
|
199
|
+
],
|
|
200
|
+
"description": "`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"
|
|
201
|
+
},
|
|
202
|
+
"expected": {
|
|
203
|
+
"type": "integer",
|
|
204
|
+
"minimum": 0,
|
|
205
|
+
"maximum": 9007199254740991
|
|
206
|
+
},
|
|
207
|
+
"published": {
|
|
208
|
+
"type": "integer",
|
|
209
|
+
"minimum": 0,
|
|
210
|
+
"maximum": 9007199254740991,
|
|
211
|
+
"description": "Of the expected recordings, uploaded or referenced by address"
|
|
212
|
+
},
|
|
213
|
+
"skipped": {
|
|
214
|
+
"type": "integer",
|
|
215
|
+
"minimum": 0,
|
|
216
|
+
"maximum": 9007199254740991
|
|
217
|
+
},
|
|
218
|
+
"unresolved": {
|
|
219
|
+
"type": "integer",
|
|
220
|
+
"minimum": 0,
|
|
221
|
+
"maximum": 9007199254740991
|
|
222
|
+
},
|
|
223
|
+
"notApplicable": {
|
|
224
|
+
"type": "integer",
|
|
225
|
+
"minimum": 0,
|
|
226
|
+
"maximum": 9007199254740991
|
|
227
|
+
},
|
|
228
|
+
"layersWithoutReceipt": {
|
|
229
|
+
"type": "integer",
|
|
230
|
+
"minimum": 0,
|
|
231
|
+
"maximum": 9007199254740991,
|
|
232
|
+
"description": "Layers of the run that declared no recording expectations: nothing is claimed for them"
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
"required": [
|
|
236
|
+
"state",
|
|
237
|
+
"expected",
|
|
238
|
+
"published",
|
|
239
|
+
"skipped",
|
|
240
|
+
"unresolved",
|
|
241
|
+
"notApplicable",
|
|
242
|
+
"layersWithoutReceipt"
|
|
243
|
+
],
|
|
244
|
+
"additionalProperties": {}
|
|
245
|
+
},
|
|
182
246
|
"attachments": {
|
|
183
247
|
"description": "Files attached to the run itself, in its layers, not to a check. Absent when there are none",
|
|
184
248
|
"type": "integer",
|
|
@@ -419,6 +483,28 @@
|
|
|
419
483
|
],
|
|
420
484
|
"additionalProperties": {}
|
|
421
485
|
}
|
|
486
|
+
},
|
|
487
|
+
"recordings": {
|
|
488
|
+
"description": "Only for runs: `complete`, `incomplete`, `none-expected` and `unknown` with how many runs have each. Absent on servers that predate the filter",
|
|
489
|
+
"type": "array",
|
|
490
|
+
"items": {
|
|
491
|
+
"type": "object",
|
|
492
|
+
"properties": {
|
|
493
|
+
"value": {
|
|
494
|
+
"type": "string"
|
|
495
|
+
},
|
|
496
|
+
"count": {
|
|
497
|
+
"type": "integer",
|
|
498
|
+
"minimum": 0,
|
|
499
|
+
"maximum": 9007199254740991
|
|
500
|
+
}
|
|
501
|
+
},
|
|
502
|
+
"required": [
|
|
503
|
+
"value",
|
|
504
|
+
"count"
|
|
505
|
+
],
|
|
506
|
+
"additionalProperties": {}
|
|
507
|
+
}
|
|
422
508
|
}
|
|
423
509
|
},
|
|
424
510
|
"required": [
|
|
@@ -196,6 +196,10 @@
|
|
|
196
196
|
"type": "boolean",
|
|
197
197
|
"description": "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"
|
|
198
198
|
},
|
|
199
|
+
"reason": {
|
|
200
|
+
"description": "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",
|
|
201
|
+
"type": "string"
|
|
202
|
+
},
|
|
199
203
|
"scope": {
|
|
200
204
|
"description": "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",
|
|
201
205
|
"type": "object",
|
|
@@ -221,6 +221,10 @@
|
|
|
221
221
|
"type": "boolean",
|
|
222
222
|
"description": "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"
|
|
223
223
|
},
|
|
224
|
+
"reason": {
|
|
225
|
+
"description": "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",
|
|
226
|
+
"type": "string"
|
|
227
|
+
},
|
|
224
228
|
"scope": {
|
|
225
229
|
"description": "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",
|
|
226
230
|
"type": "object",
|
|
@@ -529,6 +529,10 @@
|
|
|
529
529
|
"kind": {
|
|
530
530
|
"type": "string"
|
|
531
531
|
},
|
|
532
|
+
"fingerprint": {
|
|
533
|
+
"description": "The fingerprint of the spec text now (the promise). Compare it with a result's `specRevision`: different means the promise changed after the result was recorded. Absent: unknown, never \"the same\". Absent from an older server",
|
|
534
|
+
"type": "string"
|
|
535
|
+
},
|
|
532
536
|
"tests": {
|
|
533
537
|
"type": "integer",
|
|
534
538
|
"minimum": 0,
|
|
@@ -747,6 +751,10 @@
|
|
|
747
751
|
},
|
|
748
752
|
"kind": {
|
|
749
753
|
"type": "string"
|
|
754
|
+
},
|
|
755
|
+
"fingerprint": {
|
|
756
|
+
"description": "The fingerprint of the spec text now (the promise). Compare it with a result's `specRevision`: different means the promise changed after the result was recorded. Absent: unknown, never \"the same\". Absent from an older server",
|
|
757
|
+
"type": "string"
|
|
750
758
|
}
|
|
751
759
|
},
|
|
752
760
|
"required": [
|
|
@@ -869,6 +877,24 @@
|
|
|
869
877
|
"description": "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",
|
|
870
878
|
"type": "string"
|
|
871
879
|
},
|
|
880
|
+
"freshness": {
|
|
881
|
+
"description": "`modified`: recorded from a checkout with uncommitted changes. `unknown`: origin not captured. Absent for a clean checkout, on results other than a test's current ones, and from an older server. Advisory; never changes a status",
|
|
882
|
+
"type": "string",
|
|
883
|
+
"enum": [
|
|
884
|
+
"modified",
|
|
885
|
+
"unknown"
|
|
886
|
+
]
|
|
887
|
+
},
|
|
888
|
+
"provenance": {
|
|
889
|
+
"description": "The labels of its layer and check that say what it ran against and who vouches for it: `build`, `platform`, `applies-to`, `applies-to-by`, `published-at`, `enriched-at`. Present on a test's current results when it has any, and absent from an older server. Never decides a result",
|
|
890
|
+
"type": "object",
|
|
891
|
+
"propertyNames": {
|
|
892
|
+
"type": "string"
|
|
893
|
+
},
|
|
894
|
+
"additionalProperties": {
|
|
895
|
+
"type": "string"
|
|
896
|
+
}
|
|
897
|
+
},
|
|
872
898
|
"evidence": {
|
|
873
899
|
"type": "object",
|
|
874
900
|
"properties": {
|
|
@@ -977,6 +1003,10 @@
|
|
|
977
1003
|
"type": "boolean",
|
|
978
1004
|
"description": "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"
|
|
979
1005
|
},
|
|
1006
|
+
"reason": {
|
|
1007
|
+
"description": "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",
|
|
1008
|
+
"type": "string"
|
|
1009
|
+
},
|
|
980
1010
|
"scope": {
|
|
981
1011
|
"description": "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",
|
|
982
1012
|
"type": "object",
|
|
@@ -45,6 +45,10 @@
|
|
|
45
45
|
},
|
|
46
46
|
"kind": {
|
|
47
47
|
"type": "string"
|
|
48
|
+
},
|
|
49
|
+
"fingerprint": {
|
|
50
|
+
"description": "The fingerprint of the spec text now (the promise). Compare it with a result's `specRevision`: different means the promise changed after the result was recorded. Absent: unknown, never \"the same\". Absent from an older server",
|
|
51
|
+
"type": "string"
|
|
48
52
|
}
|
|
49
53
|
},
|
|
50
54
|
"required": [
|
|
@@ -167,6 +171,24 @@
|
|
|
167
171
|
"description": "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",
|
|
168
172
|
"type": "string"
|
|
169
173
|
},
|
|
174
|
+
"freshness": {
|
|
175
|
+
"description": "`modified`: recorded from a checkout with uncommitted changes. `unknown`: origin not captured. Absent for a clean checkout, on results other than a test's current ones, and from an older server. Advisory; never changes a status",
|
|
176
|
+
"type": "string",
|
|
177
|
+
"enum": [
|
|
178
|
+
"modified",
|
|
179
|
+
"unknown"
|
|
180
|
+
]
|
|
181
|
+
},
|
|
182
|
+
"provenance": {
|
|
183
|
+
"description": "The labels of its layer and check that say what it ran against and who vouches for it: `build`, `platform`, `applies-to`, `applies-to-by`, `published-at`, `enriched-at`. Present on a test's current results when it has any, and absent from an older server. Never decides a result",
|
|
184
|
+
"type": "object",
|
|
185
|
+
"propertyNames": {
|
|
186
|
+
"type": "string"
|
|
187
|
+
},
|
|
188
|
+
"additionalProperties": {
|
|
189
|
+
"type": "string"
|
|
190
|
+
}
|
|
191
|
+
},
|
|
170
192
|
"evidence": {
|
|
171
193
|
"type": "object",
|
|
172
194
|
"properties": {
|
|
@@ -275,6 +297,10 @@
|
|
|
275
297
|
"type": "boolean",
|
|
276
298
|
"description": "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"
|
|
277
299
|
},
|
|
300
|
+
"reason": {
|
|
301
|
+
"description": "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",
|
|
302
|
+
"type": "string"
|
|
303
|
+
},
|
|
278
304
|
"scope": {
|
|
279
305
|
"description": "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",
|
|
280
306
|
"type": "object",
|
|
@@ -820,6 +846,24 @@
|
|
|
820
846
|
"description": "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",
|
|
821
847
|
"type": "string"
|
|
822
848
|
},
|
|
849
|
+
"freshness": {
|
|
850
|
+
"description": "`modified`: recorded from a checkout with uncommitted changes. `unknown`: origin not captured. Absent for a clean checkout, on results other than a test's current ones, and from an older server. Advisory; never changes a status",
|
|
851
|
+
"type": "string",
|
|
852
|
+
"enum": [
|
|
853
|
+
"modified",
|
|
854
|
+
"unknown"
|
|
855
|
+
]
|
|
856
|
+
},
|
|
857
|
+
"provenance": {
|
|
858
|
+
"description": "The labels of its layer and check that say what it ran against and who vouches for it: `build`, `platform`, `applies-to`, `applies-to-by`, `published-at`, `enriched-at`. Present on a test's current results when it has any, and absent from an older server. Never decides a result",
|
|
859
|
+
"type": "object",
|
|
860
|
+
"propertyNames": {
|
|
861
|
+
"type": "string"
|
|
862
|
+
},
|
|
863
|
+
"additionalProperties": {
|
|
864
|
+
"type": "string"
|
|
865
|
+
}
|
|
866
|
+
},
|
|
823
867
|
"evidence": {
|
|
824
868
|
"type": "object",
|
|
825
869
|
"properties": {
|
|
@@ -928,6 +972,10 @@
|
|
|
928
972
|
"type": "boolean",
|
|
929
973
|
"description": "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"
|
|
930
974
|
},
|
|
975
|
+
"reason": {
|
|
976
|
+
"description": "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",
|
|
977
|
+
"type": "string"
|
|
978
|
+
},
|
|
931
979
|
"scope": {
|
|
932
980
|
"description": "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",
|
|
933
981
|
"type": "object",
|