@crvouga/atlas 1.2.0 → 1.3.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 (43) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/reports/src/evidence-detail.d.ts +14 -3
  3. package/dist/reports/src/evidence-detail.js +33 -19
  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/layer-merge.js +3 -2
  9. package/dist/reports/src/layer-types.d.ts +1 -1
  10. package/dist/reports/src/publish-checks.js +1 -0
  11. package/dist/reports/src/reporter.d.ts +1 -1
  12. package/dist/reports/src/reports-explorer-route.d.ts +276 -0
  13. package/dist/reports/src/reports-route.d.ts +276 -0
  14. package/dist/reports/src/test-catalog.d.ts +7 -1
  15. package/dist/reports/src/test-catalog.js +15 -3
  16. package/dist/schema/src/api.d.ts +520 -0
  17. package/dist/schema/src/api.js +7 -4
  18. package/dist/schema/src/layer.d.ts +981 -0
  19. package/dist/schema/src/layer.js +43 -4
  20. package/dist/server/src/openapi.js +1 -0
  21. package/docs/extending.md +1 -0
  22. package/docs/reference/http-api.md +2 -0
  23. package/docs/reference/reports.md +179 -7
  24. package/docs/reference/schema.md +23 -0
  25. package/docs/rich-evidence.md +47 -0
  26. package/llms-full.txt +50 -0
  27. package/package.json +1 -1
  28. package/packages/schema/schemas/check-detail.schema.json +673 -1
  29. package/packages/schema/schemas/effective-delta.schema.json +192 -0
  30. package/packages/schema/schemas/effective-evidence.schema.json +192 -0
  31. package/packages/schema/schemas/evidence-page.schema.json +96 -0
  32. package/packages/schema/schemas/layer-rows.schema.json +96 -0
  33. package/packages/schema/schemas/layer.schema.json +1598 -62
  34. package/packages/schema/schemas/publish-checks.schema.json +768 -0
  35. package/packages/schema/schemas/report-run.schema.json +96 -0
  36. package/packages/schema/schemas/test-catalog.schema.json +128 -0
  37. package/packages/schema/schemas/test-history.schema.json +202 -0
  38. package/packages/server/openapi.json +2581 -23
  39. package/packages/visualizer/src/evidence/artifacts.tsx +24 -18
  40. package/packages/visualizer/src/evidence/evidence-scope.tsx +106 -0
  41. package/packages/visualizer/src/evidence/format.ts +11 -0
  42. package/packages/visualizer/src/explorer/Explorer.tsx +19 -0
  43. package/packages/visualizer/src/explorer/search.ts +5 -1
@@ -192,6 +192,102 @@
192
192
  "available": {
193
193
  "type": "boolean",
194
194
  "description": "False when the reference names no bytes (no bundle key, address or inline text)"
195
+ },
196
+ "scope": {
197
+ "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",
198
+ "type": "object",
199
+ "properties": {
200
+ "surface": {
201
+ "description": "Where the product ran, in an open vocabulary: `browser`, `native-app`, `api`, `cli`…",
202
+ "type": "string",
203
+ "minLength": 1
204
+ },
205
+ "deviceKind": {
206
+ "description": "What it ran on, in an open vocabulary: `simulator`, `emulator`, `physical`, `virtual-machine`, `desktop`… A simulator and a physical phone stay distinct values; they are filtered separately",
207
+ "type": "string",
208
+ "minLength": 1
209
+ },
210
+ "syntheticData": {
211
+ "description": "True: the data was made up for the run. False: real data. Absent: unknown",
212
+ "type": "boolean"
213
+ },
214
+ "dependencies": {
215
+ "description": "Whether what the product talks to was `scripted` (replies fixed in advance), `live` or `mixed`. An open vocabulary; absent is unknown",
216
+ "type": "string",
217
+ "minLength": 1
218
+ },
219
+ "audioCaptured": {
220
+ "description": "True: the recording has real audio. False: it is silent. Absent: unknown",
221
+ "type": "boolean"
222
+ },
223
+ "pacing": {
224
+ "description": "How time ran, in an open vocabulary: `paced` (slowed or scripted for a viewer), `real-time`. Absent: unknown",
225
+ "type": "string",
226
+ "minLength": 1
227
+ },
228
+ "asserted": {
229
+ "description": "The boundaries the result actually asserts. Activity visible in a recording beyond them is not verified behavior",
230
+ "type": "array",
231
+ "items": {
232
+ "type": "string"
233
+ }
234
+ },
235
+ "limitations": {
236
+ "description": "Known limits of what this evidence shows, in the producer's words",
237
+ "type": "array",
238
+ "items": {
239
+ "type": "string"
240
+ }
241
+ },
242
+ "declaredBy": {
243
+ "description": "Who or what made this declaration: a tool, a team, a person",
244
+ "type": "string"
245
+ },
246
+ "verified": {
247
+ "description": "The names of the fields above (`surface`, `deviceKind`, `syntheticData`, `dependencies`, `audioCaptured`, `pacing`) that something independent of the producer checked. Every other field is only declared",
248
+ "type": "array",
249
+ "items": {
250
+ "type": "string"
251
+ }
252
+ },
253
+ "verifiedBy": {
254
+ "description": "What checked the `verified` fields",
255
+ "type": "string"
256
+ },
257
+ "provenance": {
258
+ "description": "Where the declaration comes from and how to check it: a document, a CI step, a device log",
259
+ "type": "array",
260
+ "items": {
261
+ "type": "object",
262
+ "properties": {
263
+ "url": {
264
+ "type": "string",
265
+ "minLength": 1
266
+ },
267
+ "name": {
268
+ "type": "string"
269
+ },
270
+ "rel": {
271
+ "description": "Why it is linked, in an open vocabulary: issue, run, trace, docs, source…",
272
+ "type": "string"
273
+ }
274
+ },
275
+ "required": [
276
+ "url"
277
+ ],
278
+ "additionalProperties": {}
279
+ }
280
+ },
281
+ "extensions": {
282
+ "type": "object",
283
+ "propertyNames": {
284
+ "type": "string",
285
+ "minLength": 1
286
+ },
287
+ "additionalProperties": {}
288
+ }
289
+ },
290
+ "additionalProperties": {}
195
291
  }
196
292
  },
197
293
  "required": [
@@ -489,6 +585,102 @@
489
585
  "available": {
490
586
  "type": "boolean",
491
587
  "description": "False when the reference names no bytes (no bundle key, address or inline text)"
588
+ },
589
+ "scope": {
590
+ "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",
591
+ "type": "object",
592
+ "properties": {
593
+ "surface": {
594
+ "description": "Where the product ran, in an open vocabulary: `browser`, `native-app`, `api`, `cli`…",
595
+ "type": "string",
596
+ "minLength": 1
597
+ },
598
+ "deviceKind": {
599
+ "description": "What it ran on, in an open vocabulary: `simulator`, `emulator`, `physical`, `virtual-machine`, `desktop`… A simulator and a physical phone stay distinct values; they are filtered separately",
600
+ "type": "string",
601
+ "minLength": 1
602
+ },
603
+ "syntheticData": {
604
+ "description": "True: the data was made up for the run. False: real data. Absent: unknown",
605
+ "type": "boolean"
606
+ },
607
+ "dependencies": {
608
+ "description": "Whether what the product talks to was `scripted` (replies fixed in advance), `live` or `mixed`. An open vocabulary; absent is unknown",
609
+ "type": "string",
610
+ "minLength": 1
611
+ },
612
+ "audioCaptured": {
613
+ "description": "True: the recording has real audio. False: it is silent. Absent: unknown",
614
+ "type": "boolean"
615
+ },
616
+ "pacing": {
617
+ "description": "How time ran, in an open vocabulary: `paced` (slowed or scripted for a viewer), `real-time`. Absent: unknown",
618
+ "type": "string",
619
+ "minLength": 1
620
+ },
621
+ "asserted": {
622
+ "description": "The boundaries the result actually asserts. Activity visible in a recording beyond them is not verified behavior",
623
+ "type": "array",
624
+ "items": {
625
+ "type": "string"
626
+ }
627
+ },
628
+ "limitations": {
629
+ "description": "Known limits of what this evidence shows, in the producer's words",
630
+ "type": "array",
631
+ "items": {
632
+ "type": "string"
633
+ }
634
+ },
635
+ "declaredBy": {
636
+ "description": "Who or what made this declaration: a tool, a team, a person",
637
+ "type": "string"
638
+ },
639
+ "verified": {
640
+ "description": "The names of the fields above (`surface`, `deviceKind`, `syntheticData`, `dependencies`, `audioCaptured`, `pacing`) that something independent of the producer checked. Every other field is only declared",
641
+ "type": "array",
642
+ "items": {
643
+ "type": "string"
644
+ }
645
+ },
646
+ "verifiedBy": {
647
+ "description": "What checked the `verified` fields",
648
+ "type": "string"
649
+ },
650
+ "provenance": {
651
+ "description": "Where the declaration comes from and how to check it: a document, a CI step, a device log",
652
+ "type": "array",
653
+ "items": {
654
+ "type": "object",
655
+ "properties": {
656
+ "url": {
657
+ "type": "string",
658
+ "minLength": 1
659
+ },
660
+ "name": {
661
+ "type": "string"
662
+ },
663
+ "rel": {
664
+ "description": "Why it is linked, in an open vocabulary: issue, run, trace, docs, source…",
665
+ "type": "string"
666
+ }
667
+ },
668
+ "required": [
669
+ "url"
670
+ ],
671
+ "additionalProperties": {}
672
+ }
673
+ },
674
+ "extensions": {
675
+ "type": "object",
676
+ "propertyNames": {
677
+ "type": "string",
678
+ "minLength": 1
679
+ },
680
+ "additionalProperties": {}
681
+ }
682
+ },
683
+ "additionalProperties": {}
492
684
  }
493
685
  },
494
686
  "required": [
@@ -192,6 +192,102 @@
192
192
  "available": {
193
193
  "type": "boolean",
194
194
  "description": "False when the reference names no bytes (no bundle key, address or inline text)"
195
+ },
196
+ "scope": {
197
+ "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",
198
+ "type": "object",
199
+ "properties": {
200
+ "surface": {
201
+ "description": "Where the product ran, in an open vocabulary: `browser`, `native-app`, `api`, `cli`…",
202
+ "type": "string",
203
+ "minLength": 1
204
+ },
205
+ "deviceKind": {
206
+ "description": "What it ran on, in an open vocabulary: `simulator`, `emulator`, `physical`, `virtual-machine`, `desktop`… A simulator and a physical phone stay distinct values; they are filtered separately",
207
+ "type": "string",
208
+ "minLength": 1
209
+ },
210
+ "syntheticData": {
211
+ "description": "True: the data was made up for the run. False: real data. Absent: unknown",
212
+ "type": "boolean"
213
+ },
214
+ "dependencies": {
215
+ "description": "Whether what the product talks to was `scripted` (replies fixed in advance), `live` or `mixed`. An open vocabulary; absent is unknown",
216
+ "type": "string",
217
+ "minLength": 1
218
+ },
219
+ "audioCaptured": {
220
+ "description": "True: the recording has real audio. False: it is silent. Absent: unknown",
221
+ "type": "boolean"
222
+ },
223
+ "pacing": {
224
+ "description": "How time ran, in an open vocabulary: `paced` (slowed or scripted for a viewer), `real-time`. Absent: unknown",
225
+ "type": "string",
226
+ "minLength": 1
227
+ },
228
+ "asserted": {
229
+ "description": "The boundaries the result actually asserts. Activity visible in a recording beyond them is not verified behavior",
230
+ "type": "array",
231
+ "items": {
232
+ "type": "string"
233
+ }
234
+ },
235
+ "limitations": {
236
+ "description": "Known limits of what this evidence shows, in the producer's words",
237
+ "type": "array",
238
+ "items": {
239
+ "type": "string"
240
+ }
241
+ },
242
+ "declaredBy": {
243
+ "description": "Who or what made this declaration: a tool, a team, a person",
244
+ "type": "string"
245
+ },
246
+ "verified": {
247
+ "description": "The names of the fields above (`surface`, `deviceKind`, `syntheticData`, `dependencies`, `audioCaptured`, `pacing`) that something independent of the producer checked. Every other field is only declared",
248
+ "type": "array",
249
+ "items": {
250
+ "type": "string"
251
+ }
252
+ },
253
+ "verifiedBy": {
254
+ "description": "What checked the `verified` fields",
255
+ "type": "string"
256
+ },
257
+ "provenance": {
258
+ "description": "Where the declaration comes from and how to check it: a document, a CI step, a device log",
259
+ "type": "array",
260
+ "items": {
261
+ "type": "object",
262
+ "properties": {
263
+ "url": {
264
+ "type": "string",
265
+ "minLength": 1
266
+ },
267
+ "name": {
268
+ "type": "string"
269
+ },
270
+ "rel": {
271
+ "description": "Why it is linked, in an open vocabulary: issue, run, trace, docs, source…",
272
+ "type": "string"
273
+ }
274
+ },
275
+ "required": [
276
+ "url"
277
+ ],
278
+ "additionalProperties": {}
279
+ }
280
+ },
281
+ "extensions": {
282
+ "type": "object",
283
+ "propertyNames": {
284
+ "type": "string",
285
+ "minLength": 1
286
+ },
287
+ "additionalProperties": {}
288
+ }
289
+ },
290
+ "additionalProperties": {}
195
291
  }
196
292
  },
197
293
  "required": [
@@ -489,6 +585,102 @@
489
585
  "available": {
490
586
  "type": "boolean",
491
587
  "description": "False when the reference names no bytes (no bundle key, address or inline text)"
588
+ },
589
+ "scope": {
590
+ "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",
591
+ "type": "object",
592
+ "properties": {
593
+ "surface": {
594
+ "description": "Where the product ran, in an open vocabulary: `browser`, `native-app`, `api`, `cli`…",
595
+ "type": "string",
596
+ "minLength": 1
597
+ },
598
+ "deviceKind": {
599
+ "description": "What it ran on, in an open vocabulary: `simulator`, `emulator`, `physical`, `virtual-machine`, `desktop`… A simulator and a physical phone stay distinct values; they are filtered separately",
600
+ "type": "string",
601
+ "minLength": 1
602
+ },
603
+ "syntheticData": {
604
+ "description": "True: the data was made up for the run. False: real data. Absent: unknown",
605
+ "type": "boolean"
606
+ },
607
+ "dependencies": {
608
+ "description": "Whether what the product talks to was `scripted` (replies fixed in advance), `live` or `mixed`. An open vocabulary; absent is unknown",
609
+ "type": "string",
610
+ "minLength": 1
611
+ },
612
+ "audioCaptured": {
613
+ "description": "True: the recording has real audio. False: it is silent. Absent: unknown",
614
+ "type": "boolean"
615
+ },
616
+ "pacing": {
617
+ "description": "How time ran, in an open vocabulary: `paced` (slowed or scripted for a viewer), `real-time`. Absent: unknown",
618
+ "type": "string",
619
+ "minLength": 1
620
+ },
621
+ "asserted": {
622
+ "description": "The boundaries the result actually asserts. Activity visible in a recording beyond them is not verified behavior",
623
+ "type": "array",
624
+ "items": {
625
+ "type": "string"
626
+ }
627
+ },
628
+ "limitations": {
629
+ "description": "Known limits of what this evidence shows, in the producer's words",
630
+ "type": "array",
631
+ "items": {
632
+ "type": "string"
633
+ }
634
+ },
635
+ "declaredBy": {
636
+ "description": "Who or what made this declaration: a tool, a team, a person",
637
+ "type": "string"
638
+ },
639
+ "verified": {
640
+ "description": "The names of the fields above (`surface`, `deviceKind`, `syntheticData`, `dependencies`, `audioCaptured`, `pacing`) that something independent of the producer checked. Every other field is only declared",
641
+ "type": "array",
642
+ "items": {
643
+ "type": "string"
644
+ }
645
+ },
646
+ "verifiedBy": {
647
+ "description": "What checked the `verified` fields",
648
+ "type": "string"
649
+ },
650
+ "provenance": {
651
+ "description": "Where the declaration comes from and how to check it: a document, a CI step, a device log",
652
+ "type": "array",
653
+ "items": {
654
+ "type": "object",
655
+ "properties": {
656
+ "url": {
657
+ "type": "string",
658
+ "minLength": 1
659
+ },
660
+ "name": {
661
+ "type": "string"
662
+ },
663
+ "rel": {
664
+ "description": "Why it is linked, in an open vocabulary: issue, run, trace, docs, source…",
665
+ "type": "string"
666
+ }
667
+ },
668
+ "required": [
669
+ "url"
670
+ ],
671
+ "additionalProperties": {}
672
+ }
673
+ },
674
+ "extensions": {
675
+ "type": "object",
676
+ "propertyNames": {
677
+ "type": "string",
678
+ "minLength": 1
679
+ },
680
+ "additionalProperties": {}
681
+ }
682
+ },
683
+ "additionalProperties": {}
492
684
  }
493
685
  },
494
686
  "required": [
@@ -237,6 +237,102 @@
237
237
  "available": {
238
238
  "type": "boolean",
239
239
  "description": "False when the reference names no bytes (no bundle key, address or inline text)"
240
+ },
241
+ "scope": {
242
+ "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",
243
+ "type": "object",
244
+ "properties": {
245
+ "surface": {
246
+ "description": "Where the product ran, in an open vocabulary: `browser`, `native-app`, `api`, `cli`…",
247
+ "type": "string",
248
+ "minLength": 1
249
+ },
250
+ "deviceKind": {
251
+ "description": "What it ran on, in an open vocabulary: `simulator`, `emulator`, `physical`, `virtual-machine`, `desktop`… A simulator and a physical phone stay distinct values; they are filtered separately",
252
+ "type": "string",
253
+ "minLength": 1
254
+ },
255
+ "syntheticData": {
256
+ "description": "True: the data was made up for the run. False: real data. Absent: unknown",
257
+ "type": "boolean"
258
+ },
259
+ "dependencies": {
260
+ "description": "Whether what the product talks to was `scripted` (replies fixed in advance), `live` or `mixed`. An open vocabulary; absent is unknown",
261
+ "type": "string",
262
+ "minLength": 1
263
+ },
264
+ "audioCaptured": {
265
+ "description": "True: the recording has real audio. False: it is silent. Absent: unknown",
266
+ "type": "boolean"
267
+ },
268
+ "pacing": {
269
+ "description": "How time ran, in an open vocabulary: `paced` (slowed or scripted for a viewer), `real-time`. Absent: unknown",
270
+ "type": "string",
271
+ "minLength": 1
272
+ },
273
+ "asserted": {
274
+ "description": "The boundaries the result actually asserts. Activity visible in a recording beyond them is not verified behavior",
275
+ "type": "array",
276
+ "items": {
277
+ "type": "string"
278
+ }
279
+ },
280
+ "limitations": {
281
+ "description": "Known limits of what this evidence shows, in the producer's words",
282
+ "type": "array",
283
+ "items": {
284
+ "type": "string"
285
+ }
286
+ },
287
+ "declaredBy": {
288
+ "description": "Who or what made this declaration: a tool, a team, a person",
289
+ "type": "string"
290
+ },
291
+ "verified": {
292
+ "description": "The names of the fields above (`surface`, `deviceKind`, `syntheticData`, `dependencies`, `audioCaptured`, `pacing`) that something independent of the producer checked. Every other field is only declared",
293
+ "type": "array",
294
+ "items": {
295
+ "type": "string"
296
+ }
297
+ },
298
+ "verifiedBy": {
299
+ "description": "What checked the `verified` fields",
300
+ "type": "string"
301
+ },
302
+ "provenance": {
303
+ "description": "Where the declaration comes from and how to check it: a document, a CI step, a device log",
304
+ "type": "array",
305
+ "items": {
306
+ "type": "object",
307
+ "properties": {
308
+ "url": {
309
+ "type": "string",
310
+ "minLength": 1
311
+ },
312
+ "name": {
313
+ "type": "string"
314
+ },
315
+ "rel": {
316
+ "description": "Why it is linked, in an open vocabulary: issue, run, trace, docs, source…",
317
+ "type": "string"
318
+ }
319
+ },
320
+ "required": [
321
+ "url"
322
+ ],
323
+ "additionalProperties": {}
324
+ }
325
+ },
326
+ "extensions": {
327
+ "type": "object",
328
+ "propertyNames": {
329
+ "type": "string",
330
+ "minLength": 1
331
+ },
332
+ "additionalProperties": {}
333
+ }
334
+ },
335
+ "additionalProperties": {}
240
336
  }
241
337
  },
242
338
  "required": [
@@ -183,6 +183,102 @@
183
183
  "available": {
184
184
  "type": "boolean",
185
185
  "description": "False when the reference names no bytes (no bundle key, address or inline text)"
186
+ },
187
+ "scope": {
188
+ "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",
189
+ "type": "object",
190
+ "properties": {
191
+ "surface": {
192
+ "description": "Where the product ran, in an open vocabulary: `browser`, `native-app`, `api`, `cli`…",
193
+ "type": "string",
194
+ "minLength": 1
195
+ },
196
+ "deviceKind": {
197
+ "description": "What it ran on, in an open vocabulary: `simulator`, `emulator`, `physical`, `virtual-machine`, `desktop`… A simulator and a physical phone stay distinct values; they are filtered separately",
198
+ "type": "string",
199
+ "minLength": 1
200
+ },
201
+ "syntheticData": {
202
+ "description": "True: the data was made up for the run. False: real data. Absent: unknown",
203
+ "type": "boolean"
204
+ },
205
+ "dependencies": {
206
+ "description": "Whether what the product talks to was `scripted` (replies fixed in advance), `live` or `mixed`. An open vocabulary; absent is unknown",
207
+ "type": "string",
208
+ "minLength": 1
209
+ },
210
+ "audioCaptured": {
211
+ "description": "True: the recording has real audio. False: it is silent. Absent: unknown",
212
+ "type": "boolean"
213
+ },
214
+ "pacing": {
215
+ "description": "How time ran, in an open vocabulary: `paced` (slowed or scripted for a viewer), `real-time`. Absent: unknown",
216
+ "type": "string",
217
+ "minLength": 1
218
+ },
219
+ "asserted": {
220
+ "description": "The boundaries the result actually asserts. Activity visible in a recording beyond them is not verified behavior",
221
+ "type": "array",
222
+ "items": {
223
+ "type": "string"
224
+ }
225
+ },
226
+ "limitations": {
227
+ "description": "Known limits of what this evidence shows, in the producer's words",
228
+ "type": "array",
229
+ "items": {
230
+ "type": "string"
231
+ }
232
+ },
233
+ "declaredBy": {
234
+ "description": "Who or what made this declaration: a tool, a team, a person",
235
+ "type": "string"
236
+ },
237
+ "verified": {
238
+ "description": "The names of the fields above (`surface`, `deviceKind`, `syntheticData`, `dependencies`, `audioCaptured`, `pacing`) that something independent of the producer checked. Every other field is only declared",
239
+ "type": "array",
240
+ "items": {
241
+ "type": "string"
242
+ }
243
+ },
244
+ "verifiedBy": {
245
+ "description": "What checked the `verified` fields",
246
+ "type": "string"
247
+ },
248
+ "provenance": {
249
+ "description": "Where the declaration comes from and how to check it: a document, a CI step, a device log",
250
+ "type": "array",
251
+ "items": {
252
+ "type": "object",
253
+ "properties": {
254
+ "url": {
255
+ "type": "string",
256
+ "minLength": 1
257
+ },
258
+ "name": {
259
+ "type": "string"
260
+ },
261
+ "rel": {
262
+ "description": "Why it is linked, in an open vocabulary: issue, run, trace, docs, source…",
263
+ "type": "string"
264
+ }
265
+ },
266
+ "required": [
267
+ "url"
268
+ ],
269
+ "additionalProperties": {}
270
+ }
271
+ },
272
+ "extensions": {
273
+ "type": "object",
274
+ "propertyNames": {
275
+ "type": "string",
276
+ "minLength": 1
277
+ },
278
+ "additionalProperties": {}
279
+ }
280
+ },
281
+ "additionalProperties": {}
186
282
  }
187
283
  },
188
284
  "required": [