@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
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
|
|
|
@@ -1015,6 +1016,7 @@ decided exactly as before ([the report contract](report-contract.md)). Evidence
|
|
|
1015
1016
|
| `attempts` | check | Every try of a retried check, with its own status, detail, steps and attachments. A check that passed after failing is flaky. |
|
|
1016
1017
|
| `tags`, `labels` | check, layer | Filters and groups (`smoke`, `flaky`, an owner, a browser). |
|
|
1017
1018
|
| `tags` | attachment | Marks one recording or screenshot, for example `demo`: shown as a `#demo` chip, and searchable. See [Tagging artifacts and demos](#tagging-artifacts-and-demos). |
|
|
1019
|
+
| `poster` (the `id` of an image in the same list) and `durationMs` | attachment (video) | Shown beside the recording in a watch playlist before anything is opened: the report carries them as the optional `poster` (a bundle key) and `durationMs` of each video reference, so no evidence is read per entry. Neither is ever a latency. |
|
|
1018
1020
|
| `extensions['atlas.media']` | attachment (video) | Where the check's steps are in the recording, so a click on a step seeks the video. See [Place steps in a recording](#place-steps-in-a-recording). |
|
|
1019
1021
|
| `scope` | attachment, attempt, check, part, layer | What a recording does and does not show: where it ran, whether data and dependencies were real, whether audio was captured. See [Evidence scope](#evidence-scope). |
|
|
1020
1022
|
| `annotations`, `links` | check, step, attempt, layer | Notes, warnings and issue links next to the result. |
|
|
@@ -1196,7 +1198,8 @@ curl "$ATLAS_SERVER_URL/api/reports/artifacts?artifactTag=demo&type=video&domain
|
|
|
1196
1198
|
- **Dimensions.** `artifactTag`, `type` (the media type as a role: `video`, `image`, `audio`, `snapshot`, `text`,
|
|
1197
1199
|
`file`; `video` means a playable recording), `label` (`key=value`, or `key`), `domain` and `spec` (artifacts only),
|
|
1198
1200
|
`environment` (the device or client), `producer`, `branch`, `sha` (seven or more characters), `outcome` (`passed`,
|
|
1199
|
-
`failed`, `running`, `not-run`), `
|
|
1201
|
+
`failed`, `running`, `not-run`), `recordings` (runs only: `complete`, `incomplete`, `none-expected` or `unknown`, see
|
|
1202
|
+
[recording completeness](#recording-completeness)), `since` and `until` (epoch milliseconds or an ISO date), and `q` (words).
|
|
1200
1203
|
- **Semantics.** Filters combine with AND across dimensions and OR within one (`environment=ios,android`). With both
|
|
1201
1204
|
`artifactTag` and `type`, one attachment must be both where the report says which video carries which tag: a tagged
|
|
1202
1205
|
screenshot beside an untagged video is not a tagged video. `inherited=1` also counts the tags an attachment inherits
|
|
@@ -1463,10 +1466,36 @@ publish; it never contains a path or a token.
|
|
|
1463
1466
|
retry (publishing again reuses the stored files).
|
|
1464
1467
|
- `atlas report status --format json` has `recordings`: `state` is `complete`, `incomplete`, `none-expected` or
|
|
1465
1468
|
`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
|
-
|
|
1469
|
+
- The viewer shows `Recordings 2 of 3: incomplete` beside the run's origin and in each row of the Runs tab, apart from
|
|
1470
|
+
its green or red outcomes.
|
|
1471
|
+
- **Find runs by completeness.** `GET /api/reports/runs?recordings=incomplete` (and the Runs tab's *Recordings* filter,
|
|
1472
|
+
`?tab=runs&recordings=incomplete`) keep the runs whose layers have a skipped or unresolved expected recording. The
|
|
1473
|
+
values are `complete`, `incomplete`, `none-expected` and `unknown`, comma-separated for OR, and they combine with the
|
|
1474
|
+
other filters by AND. A run whose layers declared no expectations is `unknown`, never `complete`, and a run with any
|
|
1475
|
+
layer without a receipt cannot be `complete`. It is answered from the layers' receipts, before the page limit, and
|
|
1476
|
+
never reads a recording; the facet counts say how many runs have each state. It is a property of a run, so the
|
|
1477
|
+
artifacts list does not take it. A server that predates it ignores the parameter and does not name it in `filters`, and
|
|
1478
|
+
the viewer then says the list is not narrowed by it.
|
|
1479
|
+
|
|
1480
|
+
### Is the recording still there?
|
|
1481
|
+
|
|
1482
|
+
A receipt says a file was published. Whether it is still retrievable later is a separate question, and Atlas answers it
|
|
1483
|
+
two ways without touching a check's result:
|
|
1484
|
+
|
|
1485
|
+
- **Layer bundle.** A video that names a `bundleKey` the layer's bundle does not list (the file was acknowledged and is
|
|
1486
|
+
gone, or never arrived) is not offered to play. The report marks it `available: false` with `reason: "not-in-bundle"`,
|
|
1487
|
+
the run counts it in `videos.unavailable` and `videos.missing`, and the Runs tab explains that the run stored the file
|
|
1488
|
+
but no longer holds it, which is different from a reference that never named any bytes.
|
|
1489
|
+
- **`atlas report verify-recordings`** reads the videos of the stored layers back and checks, for each, that the bundle
|
|
1490
|
+
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
|
|
1491
|
+
the container its media type names (WebM, MP4, QuickTime, Ogg, AVI). It exits 1 and names the layer and check for
|
|
1492
|
+
every gap (`not-in-bundle`, `blob-missing`, `unreadable`, `size-mismatch`, `checksum-mismatch`, `undecodable`);
|
|
1493
|
+
`--format json` prints the `verify-recordings-result` document. `--layer <id>` and `--limit <n>` narrow the work, since
|
|
1494
|
+
it reads blobs. A store that cannot answer is `unreadable`, never verified. Test results are unchanged either way.
|
|
1495
|
+
|
|
1496
|
+
Both are statements about stored bytes. Atlas does not check that a stored video plays in a given browser (a valid header
|
|
1497
|
+
can still have an unsupported codec or be truncated), and acknowledging an upload is not playback. Videos given only by
|
|
1498
|
+
`uri` are counted as referenced and not checked.
|
|
1470
1499
|
</doc>
|
|
1471
1500
|
|
|
1472
1501
|
<doc path="docs/ui-catalog.md">
|
|
@@ -2058,7 +2087,7 @@ with `format=markdown` (or `Accept: text/markdown`), and takes the project prefi
|
|
|
2058
2087
|
| One test: every recorded result (status, duration, environment, branch, commit, CI run), newest first | `GET /api/reports/tests/history?key=<key>` |
|
|
2059
2088
|
| 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
2089
|
| 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` |
|
|
2090
|
+
| 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
2091
|
| 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
2092
|
| Every test one run recorded | `GET /api/reports/runs/detail?key=<run key>` |
|
|
2064
2093
|
|
|
@@ -4532,6 +4561,37 @@ when Watch is on screen.
|
|
|
4532
4561
|
- The spec index searches titles, paths and declared domains, and can group by the domain from spec metadata (specs with
|
|
4533
4562
|
none are listed under "No domain declared"; the Tests view reports domain problems).
|
|
4534
4563
|
|
|
4564
|
+
## Behaviors across the project
|
|
4565
|
+
|
|
4566
|
+
`/behaviors` (`evidence/behaviors-page.tsx`, **Behaviors** in the spec-type menu) lists every behavior of every Gherkin feature in one
|
|
4567
|
+
place, so the question "what does this product promise?" needs no knowledge of which file holds the answer. It adds no source of
|
|
4568
|
+
truth: `evidence/behavior-index.ts` reads each feature through the same `featureBehaviors` the feature page uses, so a behavior has the
|
|
4569
|
+
same coverage state, revisions and recording in both.
|
|
4570
|
+
|
|
4571
|
+
- The list is searched with the shared matcher (`find/`: words, quoted phrases, `status:`, `domain:`, `tag:`, `has:video`), grouped by
|
|
4572
|
+
the domain spec metadata declares ("No domain declared" when it declares none), or ranked best match first when words are typed.
|
|
4573
|
+
A coverage state is a filter with its own count; `demonstrated` is always named. A long list is bounded with *Show more*.
|
|
4574
|
+
- Features whose text has not arrived are counted ("3 of 12 read"), and features that cannot be parsed are named, so an empty answer is
|
|
4575
|
+
never taken for "no such behavior" while it is still incomplete.
|
|
4576
|
+
- The search words (`q`), the coverage filter (`coverage`), the selection (`behavior`) and the expanded state (`workspace`) are in the
|
|
4577
|
+
address. Selecting shows the Read / Watch / Inspect panel beside the list (below it on narrow screens), and *Read and watch* in the
|
|
4578
|
+
selected-behavior bar is reachable before the list in keyboard order.
|
|
4579
|
+
- **Read and watch workspace.** Expanding a behavior replaces the index with a page that uses the width: a two-column
|
|
4580
|
+
`SimpleGrid` (one column below `md`) with *What should happen* (the steps, an outline's example filled in) beside *Recording* (the
|
|
4581
|
+
player, status and provenance, promise and evidence revisions, applicability), the scoped summary below, and Inspect behind a
|
|
4582
|
+
disclosure that reads the technical record only when opened. Keyboard focus moves to the behavior's heading on arrival, and
|
|
4583
|
+
*Previous behavior* / *Next behavior* move through the same search. A recording is labelled illustrative.
|
|
4584
|
+
- **Returning** from the workspace restores the search words, the filter and the selection from the address, and the scroll position,
|
|
4585
|
+
the number of rows shown and the focused row from `evidence/behavior-return.ts`, which remembers them for the session against the
|
|
4586
|
+
scope they were taken in and gives them back once, only to that scope. Storage that is unavailable means the list opens at its top.
|
|
4587
|
+
- **Scoped summary** (`evidence/scoped-summary.ts`, `scoped-summary-view.tsx`, on Watch and in the workspace) answers three questions
|
|
4588
|
+
apart, for the check in the environment of the recording shown (environments are not pooled; with none named it says they are):
|
|
4589
|
+
the **outcome** of the shown result (`outcomeHeadline`), **reliability** (`reports/reliability`: always with the independent
|
|
4590
|
+
executions it rests on, "Insufficient evidence" below the minimum, first-try success only from recorded tries, the library's
|
|
4591
|
+
warnings) and **performance** (`reports/latency`: only measurements named `product-latency`, percentiles withheld with the reason,
|
|
4592
|
+
budget and breaches). Absent evidence is stated as unknown, never as good; the test's duration is not product latency, and the
|
|
4593
|
+
summary says it describes the checks Atlas holds, not production. The full reliability and latency detail is one link away.
|
|
4594
|
+
|
|
4535
4595
|
## Catalog health
|
|
4536
4596
|
|
|
4537
4597
|
The **Catalog health** tab (`explorer/HealthView.tsx`, `?tab=health`; `@crvouga/atlas/reports/catalog-health`) explains why the Specs
|
|
@@ -4637,7 +4697,14 @@ over the same filtered set the page lists, in the same order (`explorer/playlist
|
|
|
4637
4697
|
demonstrated. A set longer than the page's limit says it is only the newest results.
|
|
4638
4698
|
- Only the selected clip is read: the list is the metadata the catalog already sent, the selected result's evidence is read
|
|
4639
4699
|
when it is selected, and the one `<video>` uses `preload="metadata"`. Opening the playlist downloads no recordings in bulk.
|
|
4640
|
-
|
|
4700
|
+
An unselected entry still shows a poster and a length when the catalog already carries them: the producer's declared
|
|
4701
|
+
`Attachment.durationMs` and `Attachment.poster` (an image of the same list that the layer's bundle holds) travel as the
|
|
4702
|
+
optional `durationMs` and `poster` of the result's video reference. The poster is an `<img loading="lazy">`, fetched when
|
|
4703
|
+
its row nears the screen; an entry whose producer declared neither shows neither, and nothing is read to find out.
|
|
4704
|
+
- The open playlist is in the address (`watch=true`, and `watchClip` for the entry playing), so a link restores it over
|
|
4705
|
+
the same filters, run or collection. Opening it adds a history entry (Back closes it); moving between clips and closing
|
|
4706
|
+
it replace the current one. A `watchClip` the set no longer holds opens the first watchable entry and the address then
|
|
4707
|
+
names that one.
|
|
4641
4708
|
- One player: selecting another clip replaces it, and the position of the clip left is kept for the session so returning
|
|
4642
4709
|
resumes there. Previous/next and advancing on end move over the watchable entries; a result with nothing to play is
|
|
4643
4710
|
selected from the list to read why.
|
|
@@ -4778,6 +4845,7 @@ The narrowly scoped exceptions are:
|
|
|
4778
4845
|
| Project home | Tests/runs/artifacts/compare/catalog health tabs, a two-run comparison with promise, outcome, recording and figure tabs per behavior, a run's Artifacts (files of its layers, shared recordings, direct links), Watch playlist of a filtered set, metrics, search, status/environment/domain/artifact-tag filters, run and artifact facets with saved views, grouping, sorting, show more | Container, Tabs, SimpleGrid, Paper, TextInput, MultiSelect, Popover, Button, Accordion, Modal, Grid, Switch |
|
|
4779
4846
|
| Test detail | Current outcomes, statistics, duration graph, product latency with budgets and baselines, history, artifacts, recording; the `layer` address parameter pins it to one run's result, labelled "This run" against "Latest combined evidence" | Drawer, Table, Badge, Alert, Stage |
|
|
4780
4847
|
| Specs | All six existing kinds, overview/index with title search and folder or declared-domain grouping, Gherkin rules/scenarios/examples with a coverage summary and Read / Watch / Inspect per behavior, Quint declarations/traces, DMN tables, source text | SpecHeader, Accordion, Tabs, Table, CodeHighlightTabs, ResultRow |
|
|
4848
|
+
| Behaviors | Project-wide behavior index with search, coverage filters and a selected behavior's Read / Watch / Inspect; an expanded read-and-watch workspace with a scoped outcome, reliability and performance summary that restores scope, scroll, selection and focus on return | Container, Grid, SimpleGrid, NavLink, TextInput, Button, Paper, Accordion, Tabs |
|
|
4781
4849
|
| Statecharts | Graph, screen/event/journey details, developer metadata, chart test results | Mantine cards/navigation and product compositions; graph exception above |
|
|
4782
4850
|
| Evidence | Steps, retries, annotations, facts, unknown extensions, safe downloads and previews | List, Badge, Accordion, Code, Image, native media |
|
|
4783
4851
|
| Recordings | Pictures/video/timeline, actor selection, moments, failure jumps, timing, model-state differences | Tabs, Slider, Button, ScrollArea, Table, Progress |
|
|
@@ -5252,6 +5320,8 @@ atlas report — layered evidence for any kind of spec
|
|
|
5252
5320
|
[--specs <dir>] [--format text|json|markdown]
|
|
5253
5321
|
[--require-environments a,b] [--require-all-specs]
|
|
5254
5322
|
[--branch <name>]... [--ignore-modified]
|
|
5323
|
+
atlas report verify-recordings [--store <dir|s3://…|id=url>]... [--backends <module>] [--layer <id>]...
|
|
5324
|
+
[--limit <n>] [--branch <name>]... [--ignore-modified] [--format text|json]
|
|
5255
5325
|
atlas report merge [--store …]... [--backends <module>] --into <dir|s3://…>
|
|
5256
5326
|
atlas report doctor [--store …]... [--role publisher|reader|both]
|
|
5257
5327
|
atlas report policy --store s3://bucket/prefix [--role publisher|reader|both]
|
|
@@ -5295,6 +5365,13 @@ atlas report — layered evidence for any kind of spec
|
|
|
5295
5365
|
--require-all-specs fail while any spec has no results
|
|
5296
5366
|
--branch <name> only layers recorded on this branch (repeatable)
|
|
5297
5367
|
--ignore-modified leave out layers from modified checkouts and unknown origins
|
|
5368
|
+
verify-recordings Read back the videos the layers published and check they are still there as published: the
|
|
5369
|
+
layer still lists the file, its blob is still stored, its size and SHA-256 are the recorded ones, and it
|
|
5370
|
+
begins like the container its media type names. Exit 1 when any video is missing, unreadable, corrupt or
|
|
5371
|
+
not that container, naming the layer and check; test results are never changed. This checks stored bytes,
|
|
5372
|
+
not playback in a browser. Videos given only by address are counted, not checked.
|
|
5373
|
+
--layer <id> only the layer whose id starts with this (repeatable; at least 7 digits)
|
|
5374
|
+
--limit <n> only the newest n layers
|
|
5298
5375
|
merge Copy the layers of several stores into one.
|
|
5299
5376
|
doctor Check that a store works: credentials, listing, writing, and what it holds.
|
|
5300
5377
|
policy Print the least-privilege IAM policy for publishers, readers, or both.
|
|
@@ -5303,8 +5380,8 @@ atlas report — layered evidence for any kind of spec
|
|
|
5303
5380
|
{ id, label?, store } (or a function returning it): a device lab, anything
|
|
5304
5381
|
that implements ObjectStore.
|
|
5305
5382
|
|
|
5306
|
-
--format json (alias --json) publish, stream, merge, doctor and
|
|
5307
|
-
(schemas: publish-result, stream-result, merge-result, doctor-result, report-status). A command
|
|
5383
|
+
--format json (alias --json) publish, stream, merge, doctor, status and verify-recordings print one JSON document instead of prose
|
|
5384
|
+
(schemas: publish-result, stream-result, merge-result, doctor-result, report-status, verify-recordings-result). A command
|
|
5308
5385
|
that is wrong is {"ok":false,"error":{"message":…,"code":"usage"}} on standard error.
|
|
5309
5386
|
A store may be an Atlas server (https://…): ATLAS_STORE=https://atlas.example.com, with ATLAS_TOKEN.
|
|
5310
5387
|
|
|
@@ -6148,6 +6225,7 @@ Every run, newest first: layers grouped by their CI run URL (else branch and com
|
|
|
6148
6225
|
- `branch` (query): Branches.
|
|
6149
6226
|
- `sha` (query): Revisions: a full commit id or a prefix of at least seven characters.
|
|
6150
6227
|
- `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`.
|
|
6228
|
+
- `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`.
|
|
6151
6229
|
- `q` (query): Words that must all appear in the title, id, spec, branch, producer, environment, tags or labels.
|
|
6152
6230
|
- `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.
|
|
6153
6231
|
- `until` (query): Only records at or before this time (same forms as `since`).
|
|
@@ -6176,6 +6254,7 @@ Scoped to one project. The same project may be selected on the unprefixed API us
|
|
|
6176
6254
|
- `branch` (query): Branches.
|
|
6177
6255
|
- `sha` (query): Revisions: a full commit id or a prefix of at least seven characters.
|
|
6178
6256
|
- `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`.
|
|
6257
|
+
- `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`.
|
|
6179
6258
|
- `q` (query): Words that must all appear in the title, id, spec, branch, producer, environment, tags or labels.
|
|
6180
6259
|
- `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.
|
|
6181
6260
|
- `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.19.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,19 @@
|
|
|
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
|
+
},
|
|
271
|
+
"durationMs": {
|
|
272
|
+
"description": "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",
|
|
273
|
+
"type": "number",
|
|
274
|
+
"minimum": 0
|
|
275
|
+
},
|
|
276
|
+
"poster": {
|
|
277
|
+
"description": "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",
|
|
278
|
+
"type": "string"
|
|
279
|
+
},
|
|
267
280
|
"scope": {
|
|
268
281
|
"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
282
|
"type": "object",
|
|
@@ -743,6 +756,19 @@
|
|
|
743
756
|
"type": "boolean",
|
|
744
757
|
"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
758
|
},
|
|
759
|
+
"reason": {
|
|
760
|
+
"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",
|
|
761
|
+
"type": "string"
|
|
762
|
+
},
|
|
763
|
+
"durationMs": {
|
|
764
|
+
"description": "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",
|
|
765
|
+
"type": "number",
|
|
766
|
+
"minimum": 0
|
|
767
|
+
},
|
|
768
|
+
"poster": {
|
|
769
|
+
"description": "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",
|
|
770
|
+
"type": "string"
|
|
771
|
+
},
|
|
746
772
|
"scope": {
|
|
747
773
|
"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
774
|
"type": "object",
|
|
@@ -264,6 +264,19 @@
|
|
|
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
|
+
},
|
|
271
|
+
"durationMs": {
|
|
272
|
+
"description": "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",
|
|
273
|
+
"type": "number",
|
|
274
|
+
"minimum": 0
|
|
275
|
+
},
|
|
276
|
+
"poster": {
|
|
277
|
+
"description": "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",
|
|
278
|
+
"type": "string"
|
|
279
|
+
},
|
|
267
280
|
"scope": {
|
|
268
281
|
"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
282
|
"type": "object",
|
|
@@ -743,6 +756,19 @@
|
|
|
743
756
|
"type": "boolean",
|
|
744
757
|
"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
758
|
},
|
|
759
|
+
"reason": {
|
|
760
|
+
"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",
|
|
761
|
+
"type": "string"
|
|
762
|
+
},
|
|
763
|
+
"durationMs": {
|
|
764
|
+
"description": "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",
|
|
765
|
+
"type": "number",
|
|
766
|
+
"minimum": 0
|
|
767
|
+
},
|
|
768
|
+
"poster": {
|
|
769
|
+
"description": "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",
|
|
770
|
+
"type": "string"
|
|
771
|
+
},
|
|
746
772
|
"scope": {
|
|
747
773
|
"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
774
|
"type": "object",
|
|
@@ -251,6 +251,19 @@
|
|
|
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
|
+
},
|
|
258
|
+
"durationMs": {
|
|
259
|
+
"description": "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",
|
|
260
|
+
"type": "number",
|
|
261
|
+
"minimum": 0
|
|
262
|
+
},
|
|
263
|
+
"poster": {
|
|
264
|
+
"description": "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",
|
|
265
|
+
"type": "string"
|
|
266
|
+
},
|
|
254
267
|
"scope": {
|
|
255
268
|
"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
269
|
"type": "object",
|
|
@@ -255,6 +255,19 @@
|
|
|
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
|
+
},
|
|
262
|
+
"durationMs": {
|
|
263
|
+
"description": "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",
|
|
264
|
+
"type": "number",
|
|
265
|
+
"minimum": 0
|
|
266
|
+
},
|
|
267
|
+
"poster": {
|
|
268
|
+
"description": "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",
|
|
269
|
+
"type": "string"
|
|
270
|
+
},
|
|
258
271
|
"scope": {
|
|
259
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",
|
|
260
273
|
"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,19 @@
|
|
|
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
|
+
},
|
|
387
|
+
"durationMs": {
|
|
388
|
+
"description": "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",
|
|
389
|
+
"type": "number",
|
|
390
|
+
"minimum": 0
|
|
391
|
+
},
|
|
392
|
+
"poster": {
|
|
393
|
+
"description": "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",
|
|
394
|
+
"type": "string"
|
|
395
|
+
},
|
|
319
396
|
"scope": {
|
|
320
397
|
"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
398
|
"type": "object",
|
|
@@ -517,6 +594,12 @@
|
|
|
517
594
|
"minimum": 0,
|
|
518
595
|
"maximum": 9007199254740991,
|
|
519
596
|
"description": "References that name no bytes, or bytes the layer does not hold"
|
|
597
|
+
},
|
|
598
|
+
"missing": {
|
|
599
|
+
"description": "Of `unavailable`, those that name a file the layer's bundle does not hold (stored, then gone). Absent when there are none",
|
|
600
|
+
"type": "integer",
|
|
601
|
+
"exclusiveMinimum": 0,
|
|
602
|
+
"maximum": 9007199254740991
|
|
520
603
|
}
|
|
521
604
|
},
|
|
522
605
|
"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,19 @@
|
|
|
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
|
+
},
|
|
203
|
+
"durationMs": {
|
|
204
|
+
"description": "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",
|
|
205
|
+
"type": "number",
|
|
206
|
+
"minimum": 0
|
|
207
|
+
},
|
|
208
|
+
"poster": {
|
|
209
|
+
"description": "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",
|
|
210
|
+
"type": "string"
|
|
211
|
+
},
|
|
199
212
|
"scope": {
|
|
200
213
|
"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
214
|
"type": "object",
|
|
@@ -221,6 +221,19 @@
|
|
|
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
|
+
},
|
|
228
|
+
"durationMs": {
|
|
229
|
+
"description": "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",
|
|
230
|
+
"type": "number",
|
|
231
|
+
"minimum": 0
|
|
232
|
+
},
|
|
233
|
+
"poster": {
|
|
234
|
+
"description": "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",
|
|
235
|
+
"type": "string"
|
|
236
|
+
},
|
|
224
237
|
"scope": {
|
|
225
238
|
"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
239
|
"type": "object",
|
|
@@ -1003,6 +1003,19 @@
|
|
|
1003
1003
|
"type": "boolean",
|
|
1004
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"
|
|
1005
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
|
+
},
|
|
1010
|
+
"durationMs": {
|
|
1011
|
+
"description": "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",
|
|
1012
|
+
"type": "number",
|
|
1013
|
+
"minimum": 0
|
|
1014
|
+
},
|
|
1015
|
+
"poster": {
|
|
1016
|
+
"description": "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",
|
|
1017
|
+
"type": "string"
|
|
1018
|
+
},
|
|
1006
1019
|
"scope": {
|
|
1007
1020
|
"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",
|
|
1008
1021
|
"type": "object",
|