@crvouga/atlas 1.2.0 → 1.4.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/reports/src/evidence-detail.d.ts +37 -3
  3. package/dist/reports/src/evidence-detail.js +52 -20
  4. package/dist/reports/src/evidence-scope.d.ts +83 -0
  5. package/dist/reports/src/evidence-scope.js +129 -0
  6. package/dist/reports/src/evidence-types.d.ts +3 -1
  7. package/dist/reports/src/explorer-types.d.ts +1 -1
  8. package/dist/reports/src/export-evidence.js +1 -1
  9. package/dist/reports/src/layer-merge.js +3 -2
  10. package/dist/reports/src/layer-types.d.ts +1 -1
  11. package/dist/reports/src/layers-route.d.ts +2 -1
  12. package/dist/reports/src/layers-route.js +8 -4
  13. package/dist/reports/src/publish-checks.js +1 -0
  14. package/dist/reports/src/reporter.d.ts +1 -1
  15. package/dist/reports/src/reports-explorer-route.d.ts +276 -0
  16. package/dist/reports/src/reports-route.d.ts +276 -0
  17. package/dist/reports/src/test-catalog.d.ts +34 -1
  18. package/dist/reports/src/test-catalog.js +23 -5
  19. package/dist/schema/src/api.d.ts +542 -0
  20. package/dist/schema/src/api.js +17 -5
  21. package/dist/schema/src/layer.d.ts +981 -0
  22. package/dist/schema/src/layer.js +43 -4
  23. package/dist/server/src/openapi.js +3 -2
  24. package/docs/extending.md +1 -0
  25. package/docs/reference/http-api.md +6 -4
  26. package/docs/reference/reports.md +243 -14
  27. package/docs/reference/schema.md +23 -0
  28. package/docs/rich-evidence.md +70 -0
  29. package/docs/ui.md +1 -1
  30. package/llms-full.txt +78 -5
  31. package/package.json +1 -1
  32. package/packages/schema/schemas/check-detail.schema.json +697 -1
  33. package/packages/schema/schemas/effective-delta.schema.json +192 -0
  34. package/packages/schema/schemas/effective-evidence.schema.json +192 -0
  35. package/packages/schema/schemas/evidence-page.schema.json +96 -0
  36. package/packages/schema/schemas/layer-rows.schema.json +96 -0
  37. package/packages/schema/schemas/layer.schema.json +1598 -62
  38. package/packages/schema/schemas/publish-checks.schema.json +768 -0
  39. package/packages/schema/schemas/report-run.schema.json +181 -0
  40. package/packages/schema/schemas/report-runs.schema.json +6 -0
  41. package/packages/schema/schemas/test-catalog.schema.json +128 -0
  42. package/packages/schema/schemas/test-history.schema.json +202 -0
  43. package/packages/server/openapi.json +2721 -48
  44. package/packages/visualizer/src/evidence/artifacts.tsx +77 -29
  45. package/packages/visualizer/src/evidence/evidence-scope.tsx +106 -0
  46. package/packages/visualizer/src/evidence/format.ts +11 -0
  47. package/packages/visualizer/src/explorer/Explorer.tsx +28 -5
  48. package/packages/visualizer/src/explorer/RunArtifacts.tsx +246 -0
  49. package/packages/visualizer/src/explorer/RunsView.tsx +40 -9
  50. package/packages/visualizer/src/explorer/search.ts +10 -3
@@ -27,6 +27,7 @@ decided exactly as before ([the report contract](report-contract.md)). Evidence
27
27
  | `attempts` | check | Every try of a retried check, with its own status, detail, steps and attachments. A check that passed after failing is flaky. |
28
28
  | `tags`, `labels` | check, layer | Filters and groups (`smoke`, `flaky`, an owner, a browser). |
29
29
  | `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). |
30
+ | `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). |
30
31
  | `annotations`, `links` | check, step, attempt, layer | Notes, warnings and issue links next to the result. |
31
32
  | `specPath` | check | The spec a check belongs to (a `.feature`, a test file), relative to the repository. Checks are grouped by it. |
32
33
  | `specs[]` (`path`, `domain`, `kind`, `title`) | layer | Names each spec and its group (`domain`), so a server can group checks by spec with a title even when no [spec set](integrating.md#tell-atlas-which-spec-a-check-belongs-to) has been published. |
@@ -62,6 +63,52 @@ attachments with that tag, and says how many match. Tags describe evidence; they
62
63
  - **Older layers.** A layer without attachment tags reads exactly as before. Tags on an attachment that cannot be read
63
64
  (not a list of strings) are dropped, and the attachment, check and layer stay.
64
65
 
66
+ ## Evidence scope
67
+
68
+ A green result and a video do not say whether the speech was real, the replies scripted, the audio recorded, the device
69
+ physical or a vendor substituted. Declare it where the evidence is, in an optional `scope`, and the viewer shows it as
70
+ short badges above the recording (before it is played), with the exact declaration on demand:
71
+
72
+ ```ts
73
+ {
74
+ name: 'checkout.webm', role: 'video',
75
+ scope: {
76
+ surface: 'browser', // where the product ran: browser, native-app, api…
77
+ deviceKind: 'simulator', // simulator, emulator, physical, virtual-machine, desktop…
78
+ syntheticData: true, // made-up data (false: real, absent: unknown)
79
+ dependencies: 'scripted', // scripted, live or mixed
80
+ audioCaptured: false, // false: silent, absent: unknown
81
+ pacing: 'paced', // paced, real-time
82
+ asserted: ['the receipt is shown'], // what the result stands on
83
+ limitations: ['Replies are scripted'],
84
+ declaredBy: 'checkout e2e suite',
85
+ verified: ['deviceKind'], // fields something independent checked
86
+ verifiedBy: 'device farm session log',
87
+ provenance: [{ url: 'https://farm.example/session/1', name: 'Device session' }]
88
+ }
89
+ }
90
+ ```
91
+
92
+ Every field is optional, and every value except the booleans is an open string.
93
+
94
+ - **Unknown is not live.** A recording with no scope, or a scope that does not say a thing, shows `Scope unknown` or
95
+ `Not declared`. It is never assumed live, physical, audible or end to end.
96
+ - **Declared is not verified.** Atlas shows `scope` as the producer's word. Only the fields named in `verified` are
97
+ marked verified (with `verifiedBy`), and `provenance` links where to check them. Atlas does not check any of it.
98
+ - **Only what was asserted.** `asserted` lists the boundaries the result stands on. The viewer says that other activity
99
+ visible in the clip is not verified behavior; with no `asserted` it says that no boundary was declared.
100
+ - **The nearest declaration, whole.** A recording takes the `scope` of the attachment, else its attempt, its check, its
101
+ part, its layer, in that order. It is never merged field by field, so a retry on a physical phone does not borrow
102
+ the limitations declared for the simulator try, and the badges change with the exact recording opened.
103
+ - **Filtering.** `GET /api/reports/tests?scope=device:physical,audio:recorded` (and the explorer's *Recording scope*
104
+ filter) lists tests with one playable recording that states every token: `surface:<v>`, `device:<v>`,
105
+ `data:synthetic` or `data:real`, `dependencies:<v>`, `audio:recorded` or `audio:silent`, `pacing:<v>`. A simulator
106
+ and a physical phone are separate values. Evidence that did not declare a value is never included, and `unknown`
107
+ asks for recordings that declared nothing. Each test lists its recordings' tokens as `scopeProfiles`, the facets as
108
+ `scopes`, and the search box finds the words in them.
109
+ - **It decides nothing.** A scope never changes a status, a slot or a winner. A scope an older Atlas cannot read is
110
+ dropped, and the attachment, check and layer stay.
111
+
65
112
  ## Finding runs and artifacts
66
113
 
67
114
  The viewer's **Runs** and **Artifacts** tabs and the API answer one query, so a link means the same thing everywhere.
@@ -256,6 +303,29 @@ or the command line, an attachment may name a `path` instead; `atlas report publ
256
303
  `atlas report publish --ctrf` keeps it ([native runner reporters](runners.md) cover CodeceptJS, Mocha, Jest and Node's
257
304
  test runner).
258
305
 
306
+ ## Run artifacts and direct links
307
+
308
+ Files attached to a run as a whole (top-level `attachments`: a review movie, a ZIP, an HTML gallery, a summary) are
309
+ shown under **Artifacts** when you open a run in the viewer's Runs tab, without opening any test. The movie plays
310
+ inline, an archive is a download, and each file keeps its name, role, type, size, duration and tags. They are grouped
311
+ by the layer that carries them, with who recorded it and when. A layer may hold no checks at all, only files: it is
312
+ listed with `No checks in this layer`, and a run of only such layers shows `No checks recorded`, never `0 passed`.
313
+
314
+ - **Direct link.** *Link to this file* gives an address that names the project, the run, one immutable layer and one
315
+ attachment: `#/?tab=runs&openRun=<run key>&layer=<layer id>&artifact=<id:… | key:… | name:…>`. Opened in a fresh tab
316
+ it selects that same file of that same layer, whatever runs arrived since. A link whose file is not in the layer says
317
+ so instead of showing another file.
318
+ - **Shared recordings.** Tests that reference the same bytes (same SHA-256 or bundle key) are one recording. The run's
319
+ *Recordings in tests* lists each once, with every test that references it, and a run-level file that a test also
320
+ references says so.
321
+ - **Unplayable files.** A file with no stored bytes, with an address that is not a web address, in a type the viewer
322
+ has no preview for, or that the browser cannot play, shows what is wrong and, when it can, a download.
323
+ - **Safety is unchanged.** Files are served only through the attachment route (never sniffed, sandboxed), and an HTML
324
+ archive renders in an iframe with an empty `sandbox`: it cannot run script.
325
+ - **API.** `GET /api/reports/runs/detail` lists the run's `layers` (backend, check count, file count) and
326
+ `GET /api/reports/evidence/detail/{backend}/{id}` returns what a layer carries as a whole (and, as `parts`, what its
327
+ parts carry). Both only gained optional fields.
328
+
259
329
  ## Recording completeness
260
330
 
261
331
  A green run does not say whether the videos you expected were kept and published. Atlas answers that separately from
package/docs/ui.md CHANGED
@@ -125,7 +125,7 @@ The narrowly scoped exceptions are:
125
125
  | Area | Screens/interactions | Mantine composition |
126
126
  | --- | --- | --- |
127
127
  | Shared shell | Project switching, spec navigation, run selection, connection status, diagnostics, mobile index | AppShell, Burger, NavLink, Menu, Popover, NativeSelect, Drawer |
128
- | Project home | Tests/runs/artifacts tabs, 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 |
128
+ | Project home | Tests/runs/artifacts tabs, a run's Artifacts (files of its layers, shared recordings, direct links), 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 |
129
129
  | Test detail | Current outcomes, statistics, duration graph, 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 |
130
130
  | Specs | All six existing kinds, overview/index, Gherkin rules/scenarios/examples, Quint declarations/traces, DMN tables, source text | SpecHeader, Accordion, Table, CodeHighlightTabs, ResultRow |
131
131
  | Statecharts | Graph, screen/event/journey details, developer metadata, chart test results | Mantine cards/navigation and product compositions; graph exception above |
package/llms-full.txt CHANGED
@@ -1014,6 +1014,7 @@ decided exactly as before ([the report contract](report-contract.md)). Evidence
1014
1014
  | `attempts` | check | Every try of a retried check, with its own status, detail, steps and attachments. A check that passed after failing is flaky. |
1015
1015
  | `tags`, `labels` | check, layer | Filters and groups (`smoke`, `flaky`, an owner, a browser). |
1016
1016
  | `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). |
1017
+ | `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). |
1017
1018
  | `annotations`, `links` | check, step, attempt, layer | Notes, warnings and issue links next to the result. |
1018
1019
  | `specPath` | check | The spec a check belongs to (a `.feature`, a test file), relative to the repository. Checks are grouped by it. |
1019
1020
  | `specs[]` (`path`, `domain`, `kind`, `title`) | layer | Names each spec and its group (`domain`), so a server can group checks by spec with a title even when no [spec set](integrating.md#tell-atlas-which-spec-a-check-belongs-to) has been published. |
@@ -1049,6 +1050,52 @@ attachments with that tag, and says how many match. Tags describe evidence; they
1049
1050
  - **Older layers.** A layer without attachment tags reads exactly as before. Tags on an attachment that cannot be read
1050
1051
  (not a list of strings) are dropped, and the attachment, check and layer stay.
1051
1052
 
1053
+ ## Evidence scope
1054
+
1055
+ A green result and a video do not say whether the speech was real, the replies scripted, the audio recorded, the device
1056
+ physical or a vendor substituted. Declare it where the evidence is, in an optional `scope`, and the viewer shows it as
1057
+ short badges above the recording (before it is played), with the exact declaration on demand:
1058
+
1059
+ ```ts
1060
+ {
1061
+ name: 'checkout.webm', role: 'video',
1062
+ scope: {
1063
+ surface: 'browser', // where the product ran: browser, native-app, api…
1064
+ deviceKind: 'simulator', // simulator, emulator, physical, virtual-machine, desktop…
1065
+ syntheticData: true, // made-up data (false: real, absent: unknown)
1066
+ dependencies: 'scripted', // scripted, live or mixed
1067
+ audioCaptured: false, // false: silent, absent: unknown
1068
+ pacing: 'paced', // paced, real-time
1069
+ asserted: ['the receipt is shown'], // what the result stands on
1070
+ limitations: ['Replies are scripted'],
1071
+ declaredBy: 'checkout e2e suite',
1072
+ verified: ['deviceKind'], // fields something independent checked
1073
+ verifiedBy: 'device farm session log',
1074
+ provenance: [{ url: 'https://farm.example/session/1', name: 'Device session' }]
1075
+ }
1076
+ }
1077
+ ```
1078
+
1079
+ Every field is optional, and every value except the booleans is an open string.
1080
+
1081
+ - **Unknown is not live.** A recording with no scope, or a scope that does not say a thing, shows `Scope unknown` or
1082
+ `Not declared`. It is never assumed live, physical, audible or end to end.
1083
+ - **Declared is not verified.** Atlas shows `scope` as the producer's word. Only the fields named in `verified` are
1084
+ marked verified (with `verifiedBy`), and `provenance` links where to check them. Atlas does not check any of it.
1085
+ - **Only what was asserted.** `asserted` lists the boundaries the result stands on. The viewer says that other activity
1086
+ visible in the clip is not verified behavior; with no `asserted` it says that no boundary was declared.
1087
+ - **The nearest declaration, whole.** A recording takes the `scope` of the attachment, else its attempt, its check, its
1088
+ part, its layer, in that order. It is never merged field by field, so a retry on a physical phone does not borrow
1089
+ the limitations declared for the simulator try, and the badges change with the exact recording opened.
1090
+ - **Filtering.** `GET /api/reports/tests?scope=device:physical,audio:recorded` (and the explorer's *Recording scope*
1091
+ filter) lists tests with one playable recording that states every token: `surface:<v>`, `device:<v>`,
1092
+ `data:synthetic` or `data:real`, `dependencies:<v>`, `audio:recorded` or `audio:silent`, `pacing:<v>`. A simulator
1093
+ and a physical phone are separate values. Evidence that did not declare a value is never included, and `unknown`
1094
+ asks for recordings that declared nothing. Each test lists its recordings' tokens as `scopeProfiles`, the facets as
1095
+ `scopes`, and the search box finds the words in them.
1096
+ - **It decides nothing.** A scope never changes a status, a slot or a winner. A scope an older Atlas cannot read is
1097
+ dropped, and the attachment, check and layer stay.
1098
+
1052
1099
  ## Finding runs and artifacts
1053
1100
 
1054
1101
  The viewer's **Runs** and **Artifacts** tabs and the API answer one query, so a link means the same thing everywhere.
@@ -1243,6 +1290,29 @@ or the command line, an attachment may name a `path` instead; `atlas report publ
1243
1290
  `atlas report publish --ctrf` keeps it ([native runner reporters](runners.md) cover CodeceptJS, Mocha, Jest and Node's
1244
1291
  test runner).
1245
1292
 
1293
+ ## Run artifacts and direct links
1294
+
1295
+ Files attached to a run as a whole (top-level `attachments`: a review movie, a ZIP, an HTML gallery, a summary) are
1296
+ shown under **Artifacts** when you open a run in the viewer's Runs tab, without opening any test. The movie plays
1297
+ inline, an archive is a download, and each file keeps its name, role, type, size, duration and tags. They are grouped
1298
+ by the layer that carries them, with who recorded it and when. A layer may hold no checks at all, only files: it is
1299
+ listed with `No checks in this layer`, and a run of only such layers shows `No checks recorded`, never `0 passed`.
1300
+
1301
+ - **Direct link.** *Link to this file* gives an address that names the project, the run, one immutable layer and one
1302
+ attachment: `#/?tab=runs&openRun=<run key>&layer=<layer id>&artifact=<id:… | key:… | name:…>`. Opened in a fresh tab
1303
+ it selects that same file of that same layer, whatever runs arrived since. A link whose file is not in the layer says
1304
+ so instead of showing another file.
1305
+ - **Shared recordings.** Tests that reference the same bytes (same SHA-256 or bundle key) are one recording. The run's
1306
+ *Recordings in tests* lists each once, with every test that references it, and a run-level file that a test also
1307
+ references says so.
1308
+ - **Unplayable files.** A file with no stored bytes, with an address that is not a web address, in a type the viewer
1309
+ has no preview for, or that the browser cannot play, shows what is wrong and, when it can, a download.
1310
+ - **Safety is unchanged.** Files are served only through the attachment route (never sniffed, sandboxed), and an HTML
1311
+ archive renders in an iframe with an empty `sandbox`: it cannot run script.
1312
+ - **API.** `GET /api/reports/runs/detail` lists the run's `layers` (backend, check count, file count) and
1313
+ `GET /api/reports/evidence/detail/{backend}/{id}` returns what a layer carries as a whole (and, as `parts`, what its
1314
+ parts carry). Both only gained optional fields.
1315
+
1246
1316
  ## Recording completeness
1247
1317
 
1248
1318
  A green run does not say whether the videos you expected were kept and published. Atlas answers that separately from
@@ -2757,6 +2827,7 @@ carry any of these. Every one is optional.
2757
2827
  | `attempts[]` | Every try, when the check was retried. |
2758
2828
  | `tags[]` | Free labels to filter by: `smoke`, `payments`. |
2759
2829
  | `labels{}` | Facts about the result that are not its identity: `owner`, `severity`, `browser`, `build`. |
2830
+ | `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). |
2760
2831
  | `links[]` | Where to read more: the CI run, the issue, the trace client. |
2761
2832
  | `extensions{}` | Structured data of your own or a tool's, under a name you own. |
2762
2833
  | `measurements[]` | Numbers, with units and an allowance (already part of the contract). |
@@ -3886,7 +3957,7 @@ The narrowly scoped exceptions are:
3886
3957
  | Area | Screens/interactions | Mantine composition |
3887
3958
  | --- | --- | --- |
3888
3959
  | Shared shell | Project switching, spec navigation, run selection, connection status, diagnostics, mobile index | AppShell, Burger, NavLink, Menu, Popover, NativeSelect, Drawer |
3889
- | Project home | Tests/runs/artifacts tabs, 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 |
3960
+ | Project home | Tests/runs/artifacts tabs, a run's Artifacts (files of its layers, shared recordings, direct links), 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 |
3890
3961
  | Test detail | Current outcomes, statistics, duration graph, 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 |
3891
3962
  | Specs | All six existing kinds, overview/index, Gherkin rules/scenarios/examples, Quint declarations/traces, DMN tables, source text | SpecHeader, Accordion, Table, CodeHighlightTabs, ResultRow |
3892
3963
  | Statecharts | Graph, screen/event/journey details, developer metadata, chart test results | Mantine cards/navigation and product compositions; graph exception above |
@@ -4923,6 +4994,7 @@ Send `format=markdown` (or `Accept: text/markdown`) for the same as a Markdown r
4923
4994
  - `tag` (query): Only tests with this tag. Repeatable or comma-separated.
4924
4995
  - `artifactTag` (query): Only tests with an attachment tagged this (`demo` and `#demo` are the same tag), not counting tags inherited from a check or run: the exact artifact query. `inherited=1` widens it to the tags inherited from the check and run. Repeatable or comma-separated.
4925
4996
  - `inherited` (query): With `artifactTag`: `1` also matches the tags an attachment inherits from its check and run, so a recording without a tag of its own under a run tagged `demo` is found. Without it the query is exact.
4997
+ - `scope` (query): Only tests with one playable recording that states every one of these producer-declared qualifications: `surface:<value>`, `device:<value>` (`device:physical` and `device:simulator` stay apart), `data:synthetic` or `data:real`, `dependencies:<value>`, `audio:recorded` or `audio:silent`, `pacing:<value>`. All must hold for the same recording. A recording that did not declare a value never matches it, and `unknown` matches only a recording that declared no scope. Repeatable or comma-separated.
4926
4998
  - `run` (query): Only tests recorded in this run (a `key` from `/api/reports/runs`).
4927
4999
  - `sort` (query): The order: `spec` (default: domain, spec, title), `title`, `recent`, `slowest`, `failures`, `flaky` or `runs`.
4928
5000
  - `offset` (query): Skip this many matching tests.
@@ -4954,6 +5026,7 @@ Scoped to one project. The same project may be selected on the unprefixed API us
4954
5026
  - `tag` (query): Only tests with this tag. Repeatable or comma-separated.
4955
5027
  - `artifactTag` (query): Only tests with an attachment tagged this (`demo` and `#demo` are the same tag), not counting tags inherited from a check or run: the exact artifact query. `inherited=1` widens it to the tags inherited from the check and run. Repeatable or comma-separated.
4956
5028
  - `inherited` (query): With `artifactTag`: `1` also matches the tags an attachment inherits from its check and run, so a recording without a tag of its own under a run tagged `demo` is found. Without it the query is exact.
5029
+ - `scope` (query): Only tests with one playable recording that states every one of these producer-declared qualifications: `surface:<value>`, `device:<value>` (`device:physical` and `device:simulator` stay apart), `data:synthetic` or `data:real`, `dependencies:<value>`, `audio:recorded` or `audio:silent`, `pacing:<value>`. All must hold for the same recording. A recording that did not declare a value never matches it, and `unknown` matches only a recording that declared no scope. Repeatable or comma-separated.
4957
5030
  - `run` (query): Only tests recorded in this run (a `key` from `/api/reports/runs`).
4958
5031
  - `sort` (query): The order: `spec` (default: domain, spec, title), `title`, `recent`, `slowest`, `failures`, `flaky` or `runs`.
4959
5032
  - `offset` (query): Skip this many matching tests.
@@ -5180,7 +5253,7 @@ Responses: `200` The matching results and the facets.; `304` Unchanged since the
5180
5253
 
5181
5254
  `GET /api/reports/runs/detail` · role: read
5182
5255
 
5183
- One run and its last result for every test, environment and producer it recorded, failures first. Send `format=markdown` for Markdown.
5256
+ One run and its last result for every test, environment and producer it recorded, failures first, and `layers`: each layer of the run with its backend, how many checks it recorded (zero means evidence only, never a pass) and how many files it carries as a whole. Open a layer's files with `/api/reports/evidence/detail/{backend}/{id}`. Send `format=markdown` for Markdown.
5184
5257
 
5185
5258
  - `key` (query, required): The run's `key` from `/api/reports/runs`, URL-encoded.
5186
5259
  - `format` (query): `markdown` for Markdown instead of JSON.
@@ -5192,7 +5265,7 @@ Responses: `200` The run and its results.; `304` Unchanged since the `If-None-Ma
5192
5265
 
5193
5266
  `GET /api/projects/{project}/reports/runs/detail` · role: read
5194
5267
 
5195
- One run and its last result for every test, environment and producer it recorded, failures first. Send `format=markdown` for Markdown.
5268
+ One run and its last result for every test, environment and producer it recorded, failures first, and `layers`: each layer of the run with its backend, how many checks it recorded (zero means evidence only, never a pass) and how many files it carries as a whole. Open a layer's files with `/api/reports/evidence/detail/{backend}/{id}`. Send `format=markdown` for Markdown.
5196
5269
 
5197
5270
  Scoped to one project. The same project may be selected on the unprefixed API using ?project= or X-Atlas-Project. Unknown projects return 404 on reads and are created by an authenticated upload.
5198
5271
 
@@ -5302,7 +5375,7 @@ Responses: `200` The rows.; `401` No token, or an unknown one. Send `Authorizati
5302
5375
 
5303
5376
  `GET /api/reports/evidence/detail/{backend}/{id}` · role: read
5304
5377
 
5305
- The timeline, annotations, retries, attachments and extensions of one check, and what its run carries as a whole. Without `check`, only the run's. Attachment bytes are fetched from `/api/reports/layers/{id}/blobs/{bundleKey}`.
5378
+ The timeline, annotations, retries, attachments and extensions of one check, and what its run carries as a whole. Without `check`, only the run's, and `parts`: what each part of the layer that carries files or links of its own holds. Attachment bytes are fetched from `/api/reports/layers/{id}/blobs/{bundleKey}`.
5306
5379
 
5307
5380
  - `backend` (path, required): A backend id from `/api/server`.
5308
5381
  - `id` (path, required): A layer id: 64 lowercase hex digits.
@@ -5316,7 +5389,7 @@ Responses: `200` The detail.; `401` No token, or an unknown one. Send `Authoriza
5316
5389
 
5317
5390
  `GET /api/projects/{project}/reports/evidence/detail/{backend}/{id}` · role: read
5318
5391
 
5319
- The timeline, annotations, retries, attachments and extensions of one check, and what its run carries as a whole. Without `check`, only the run's. Attachment bytes are fetched from `/api/reports/layers/{id}/blobs/{bundleKey}`.
5392
+ The timeline, annotations, retries, attachments and extensions of one check, and what its run carries as a whole. Without `check`, only the run's, and `parts`: what each part of the layer that carries files or links of its own holds. Attachment bytes are fetched from `/api/reports/layers/{id}/blobs/{bundleKey}`.
5320
5393
 
5321
5394
  Scoped to one project. The same project may be selected on the unprefixed API using ?project= or X-Atlas-Project. Unknown projects return 404 on reads and are created by an authenticated upload.
5322
5395
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crvouga/atlas",
3
- "version": "1.2.0",
3
+ "version": "1.4.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",