@crvouga/atlas 1.20.0 → 1.22.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 (114) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/dist/core/src/cli.d.ts +2 -2
  3. package/dist/core/src/cli.js +7 -1
  4. package/dist/critics/src/catalog-client.d.ts +91 -0
  5. package/dist/critics/src/catalog-client.js +194 -0
  6. package/dist/critics/src/cli-calibrate.d.ts +4 -0
  7. package/dist/critics/src/cli-calibrate.js +211 -0
  8. package/dist/critics/src/cli-common.d.ts +108 -0
  9. package/dist/critics/src/cli-common.js +155 -0
  10. package/dist/critics/src/cli-review.d.ts +4 -0
  11. package/dist/critics/src/cli-review.js +174 -0
  12. package/dist/critics/src/cli-watch.d.ts +4 -0
  13. package/dist/critics/src/cli-watch.js +191 -0
  14. package/dist/critics/src/cli.d.ts +13 -0
  15. package/dist/critics/src/cli.js +490 -0
  16. package/dist/critics/src/index.d.ts +3 -0
  17. package/dist/critics/src/index.js +3 -0
  18. package/dist/critics/src/judging.d.ts +8 -0
  19. package/dist/critics/src/llm.d.ts +120 -0
  20. package/dist/critics/src/llm.js +266 -0
  21. package/dist/critics/src/marks.d.ts +74 -0
  22. package/dist/critics/src/marks.js +76 -0
  23. package/dist/critics/src/registry.d.ts +125 -0
  24. package/dist/critics/src/registry.js +203 -0
  25. package/dist/critics/src/spool.d.ts +32 -0
  26. package/dist/critics/src/spool.js +129 -0
  27. package/dist/critics/src/uiclip.d.ts +82 -0
  28. package/dist/critics/src/uiclip.js +167 -0
  29. package/dist/reports/src/compose.d.ts +23 -1
  30. package/dist/reports/src/compose.js +29 -19
  31. package/dist/reports/src/critique-review.d.ts +111 -0
  32. package/dist/reports/src/critique-review.js +123 -0
  33. package/dist/reports/src/critique-row.d.ts +24 -0
  34. package/dist/reports/src/critique-row.js +39 -0
  35. package/dist/reports/src/evidence-types.d.ts +5 -0
  36. package/dist/reports/src/layer-merge.js +5 -0
  37. package/dist/reports/src/report-cli.d.ts +13 -0
  38. package/dist/reports/src/report-cli.js +6 -4
  39. package/dist/reports/src/report-index.d.ts +6 -0
  40. package/dist/reports/src/report-index.js +12 -0
  41. package/dist/reports/src/ui-catalog-cli.d.ts +10 -0
  42. package/dist/reports/src/ui-catalog-cli.js +391 -0
  43. package/dist/reports/src/ui-catalog-diff.d.ts +104 -0
  44. package/dist/reports/src/ui-catalog-diff.js +130 -0
  45. package/dist/reports/src/ui-catalog-entries.d.ts +147 -0
  46. package/dist/reports/src/ui-catalog-entries.js +190 -0
  47. package/dist/reports/src/ui-catalog-export.d.ts +82 -0
  48. package/dist/reports/src/ui-catalog-export.js +221 -0
  49. package/dist/reports/src/ui-catalog-publish.js +2 -2
  50. package/dist/reports/src/ui-catalog.d.ts +2 -0
  51. package/dist/reports/src/ui-catalog.js +1 -1
  52. package/dist/reports/src/ui-state.d.ts +2 -0
  53. package/dist/reports/src/ui-state.js +2 -2
  54. package/dist/schema/src/api.d.ts +653 -1
  55. package/dist/schema/src/api.js +44 -0
  56. package/dist/schema/src/cli-results.d.ts +991 -1
  57. package/dist/schema/src/cli-results.js +265 -1
  58. package/dist/schema/src/critique.d.ts +31 -0
  59. package/dist/schema/src/critique.js +26 -0
  60. package/dist/schema/src/server-config.d.ts +3 -3
  61. package/dist/server/src/app.js +28 -1
  62. package/dist/server/src/openapi.js +19 -2
  63. package/docs/agents.md +16 -2
  64. package/docs/critics.md +273 -9
  65. package/docs/extending.md +1 -1
  66. package/docs/reference/cli.md +126 -1
  67. package/docs/reference/core.md +1 -1
  68. package/docs/reference/critics.md +1131 -29
  69. package/docs/reference/http-api.md +40 -0
  70. package/docs/reference/reports.md +855 -0
  71. package/docs/reference/schema.md +197 -1
  72. package/docs/report-contract.md +2 -1
  73. package/docs/server.md +2 -0
  74. package/docs/ui-catalog.md +110 -13
  75. package/docs/ui.md +69 -2
  76. package/llms-full.txt +636 -26
  77. package/llms.txt +1 -1
  78. package/package.json +9 -1
  79. package/packages/critics/README.md +1 -0
  80. package/packages/schema/schemas/critic-calibrate-result.schema.json +274 -0
  81. package/packages/schema/schemas/critic-doctor-result.schema.json +74 -0
  82. package/packages/schema/schemas/critic-list-result.schema.json +90 -0
  83. package/packages/schema/schemas/critic-review-result.schema.json +397 -0
  84. package/packages/schema/schemas/critic-run-result.schema.json +249 -0
  85. package/packages/schema/schemas/critic-setup-result.schema.json +34 -0
  86. package/packages/schema/schemas/critic-watch-result.schema.json +211 -0
  87. package/packages/schema/schemas/critique-mark.schema.json +81 -0
  88. package/packages/schema/schemas/effective-delta.schema.json +337 -0
  89. package/packages/schema/schemas/effective-evidence.schema.json +337 -0
  90. package/packages/schema/schemas/layer-rows.schema.json +337 -0
  91. package/packages/schema/schemas/ui-catalog-diff-result.schema.json +201 -0
  92. package/packages/schema/schemas/ui-catalog-export-result.schema.json +83 -0
  93. package/packages/schema/schemas/ui-catalog-publish-result.schema.json +116 -0
  94. package/packages/schema/schemas/ui-catalog-status.schema.json +197 -0
  95. package/packages/server/openapi.json +6755 -4738
  96. package/packages/visualizer/src/app/AppShell.tsx +3 -1
  97. package/packages/visualizer/src/app/router.tsx +20 -7
  98. package/packages/visualizer/src/catalog/Picture.tsx +32 -0
  99. package/packages/visualizer/src/catalog/UiCatalogCompare.tsx +289 -0
  100. package/packages/visualizer/src/catalog/UiCatalogPage.tsx +18 -28
  101. package/packages/visualizer/src/catalog/history.ts +61 -0
  102. package/packages/visualizer/src/catalog/search.ts +14 -3
  103. package/packages/visualizer/src/components/Header.tsx +16 -4
  104. package/packages/visualizer/src/critiques/CritiquesPage.tsx +402 -0
  105. package/packages/visualizer/src/critiques/FindingOverlay.tsx +50 -0
  106. package/packages/visualizer/src/critiques/ranking.ts +54 -0
  107. package/packages/visualizer/src/critiques/search.ts +41 -0
  108. package/packages/visualizer/src/evidence/applicability-view.tsx +11 -7
  109. package/packages/visualizer/src/evidence/behaviors-page.tsx +22 -15
  110. package/packages/visualizer/src/evidence/evidence-context.tsx +2 -1
  111. package/packages/visualizer/src/explorer/Explorer.tsx +5 -0
  112. package/packages/visualizer/src/explorer/TestDetail.tsx +4 -1
  113. package/packages/visualizer/src/explorer/parts.tsx +19 -1
  114. package/packages/visualizer/src/explorer/playlist.tsx +11 -7
@@ -0,0 +1,211 @@
1
+ {
2
+ "$id": "https://github.com/crvouga/atlas/schemas/critic-watch-result.schema.json",
3
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
4
+ "type": "object",
5
+ "properties": {
6
+ "ok": {
7
+ "type": "boolean",
8
+ "description": "False when a critic failed on any entry (the exit code is then 1)"
9
+ },
10
+ "dryRun": {
11
+ "type": "boolean"
12
+ },
13
+ "server": {
14
+ "type": "string"
15
+ },
16
+ "scope": {
17
+ "type": "object",
18
+ "propertyNames": {
19
+ "type": "string"
20
+ },
21
+ "additionalProperties": {
22
+ "type": "string"
23
+ },
24
+ "description": "The choices that narrowed the catalog, as given"
25
+ },
26
+ "stoppedBy": {
27
+ "type": "string",
28
+ "enum": [
29
+ "interrupted",
30
+ "max-batches",
31
+ "budget",
32
+ "dry-run"
33
+ ],
34
+ "description": "Why the watch ended: Ctrl-C or a signal, `--max-batches`, a budget for the whole watch, or a dry run (one read)"
35
+ },
36
+ "batches": {
37
+ "type": "integer",
38
+ "minimum": 0,
39
+ "maximum": 9007199254740991,
40
+ "description": "How many times the catalog handed over something new, the catch-up on connecting included"
41
+ },
42
+ "version": {
43
+ "description": "The report version the watch had reached: resume with `--since` this. Null when nothing was read",
44
+ "type": [
45
+ "string",
46
+ "null"
47
+ ]
48
+ },
49
+ "critics": {
50
+ "type": "array",
51
+ "items": {
52
+ "type": "object",
53
+ "properties": {
54
+ "critic": {
55
+ "type": "string"
56
+ },
57
+ "version": {
58
+ "type": "string"
59
+ },
60
+ "sendsImagesTo": {
61
+ "type": [
62
+ "string",
63
+ "null"
64
+ ]
65
+ },
66
+ "entries": {
67
+ "type": "integer",
68
+ "minimum": 0,
69
+ "maximum": 9007199254740991,
70
+ "description": "Entries handed over by the catalog, counting a changed picture again"
71
+ },
72
+ "judged": {
73
+ "type": "integer",
74
+ "minimum": 0,
75
+ "maximum": 9007199254740991
76
+ },
77
+ "skipped": {
78
+ "type": "integer",
79
+ "minimum": 0,
80
+ "maximum": 9007199254740991,
81
+ "description": "Entries that already had a current critique of the same identity: no call was made"
82
+ },
83
+ "failed": {
84
+ "type": "integer",
85
+ "minimum": 0,
86
+ "maximum": 9007199254740991,
87
+ "description": "Entries recorded as failed with a reason code; the next batch that brings them, or the next run, retries them"
88
+ },
89
+ "failures": {
90
+ "type": "array",
91
+ "items": {
92
+ "type": "object",
93
+ "properties": {
94
+ "entry": {
95
+ "type": "string"
96
+ },
97
+ "reason": {
98
+ "type": "string"
99
+ }
100
+ },
101
+ "required": [
102
+ "entry",
103
+ "reason"
104
+ ],
105
+ "additionalProperties": {}
106
+ }
107
+ },
108
+ "spent": {
109
+ "type": "object",
110
+ "properties": {
111
+ "images": {
112
+ "type": "number"
113
+ },
114
+ "tokens": {
115
+ "type": "number"
116
+ },
117
+ "costUsd": {
118
+ "type": "number"
119
+ }
120
+ },
121
+ "required": [
122
+ "images",
123
+ "tokens",
124
+ "costUsd"
125
+ ],
126
+ "additionalProperties": {}
127
+ },
128
+ "published": {
129
+ "type": "object",
130
+ "properties": {
131
+ "layers": {
132
+ "type": "integer",
133
+ "minimum": 0,
134
+ "maximum": 9007199254740991
135
+ },
136
+ "critiques": {
137
+ "type": "integer",
138
+ "minimum": 0,
139
+ "maximum": 9007199254740991
140
+ }
141
+ },
142
+ "required": [
143
+ "layers",
144
+ "critiques"
145
+ ],
146
+ "additionalProperties": {}
147
+ }
148
+ },
149
+ "required": [
150
+ "critic",
151
+ "version",
152
+ "sendsImagesTo",
153
+ "entries",
154
+ "judged",
155
+ "skipped",
156
+ "failed",
157
+ "failures",
158
+ "spent",
159
+ "published"
160
+ ],
161
+ "additionalProperties": {}
162
+ }
163
+ },
164
+ "spool": {
165
+ "type": "object",
166
+ "properties": {
167
+ "flushed": {
168
+ "type": "integer",
169
+ "minimum": 0,
170
+ "maximum": 9007199254740991
171
+ },
172
+ "spooled": {
173
+ "type": "integer",
174
+ "minimum": 0,
175
+ "maximum": 9007199254740991
176
+ },
177
+ "pending": {
178
+ "type": "integer",
179
+ "minimum": 0,
180
+ "maximum": 9007199254740991
181
+ }
182
+ },
183
+ "required": [
184
+ "flushed",
185
+ "spooled",
186
+ "pending"
187
+ ],
188
+ "additionalProperties": {},
189
+ "description": "As for `critic-run-result`"
190
+ },
191
+ "warnings": {
192
+ "type": "array",
193
+ "items": {
194
+ "type": "string"
195
+ }
196
+ }
197
+ },
198
+ "required": [
199
+ "ok",
200
+ "dryRun",
201
+ "server",
202
+ "scope",
203
+ "stoppedBy",
204
+ "batches",
205
+ "version",
206
+ "critics",
207
+ "spool",
208
+ "warnings"
209
+ ],
210
+ "additionalProperties": {}
211
+ }
@@ -0,0 +1,81 @@
1
+ {
2
+ "$id": "https://github.com/crvouga/atlas/schemas/critique-mark.schema.json",
3
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
4
+ "type": "object",
5
+ "properties": {
6
+ "schema": {
7
+ "type": "integer",
8
+ "exclusiveMinimum": 0,
9
+ "maximum": 9007199254740991,
10
+ "description": "The version of this extension. 1"
11
+ },
12
+ "subject": {
13
+ "type": "object",
14
+ "properties": {
15
+ "entryKey": {
16
+ "type": "string",
17
+ "minLength": 1,
18
+ "description": "The catalog entry the marked critique is about"
19
+ },
20
+ "imageSha256": {
21
+ "type": "string",
22
+ "minLength": 1,
23
+ "description": "The hash of the picture the marked critique judged, so a mark about an earlier picture is shown as that"
24
+ }
25
+ },
26
+ "required": [
27
+ "entryKey",
28
+ "imageSha256"
29
+ ],
30
+ "additionalProperties": {}
31
+ },
32
+ "critic": {
33
+ "type": "object",
34
+ "properties": {
35
+ "name": {
36
+ "type": "string",
37
+ "minLength": 1
38
+ },
39
+ "version": {
40
+ "type": "string",
41
+ "minLength": 1
42
+ }
43
+ },
44
+ "required": [
45
+ "name"
46
+ ],
47
+ "additionalProperties": {},
48
+ "description": "The critic whose opinion is marked"
49
+ },
50
+ "finding": {
51
+ "description": "The `id` of the marked finding. Absent: the critique as a whole",
52
+ "type": "string",
53
+ "minLength": 1
54
+ },
55
+ "decision": {
56
+ "type": "string",
57
+ "minLength": 1,
58
+ "description": "Open vocabulary; this release understands `accept` (the opinion is right) and `dismiss` (it is not). Anything else is shown as written and counts as neither"
59
+ },
60
+ "reviewer": {
61
+ "description": "Who marked it: a name the reviewer chose, never an account",
62
+ "type": "string",
63
+ "minLength": 1
64
+ },
65
+ "note": {
66
+ "description": "Why, in the reviewer's words",
67
+ "type": "string"
68
+ },
69
+ "layer": {
70
+ "description": "The layer of the critique that was marked, for tracing",
71
+ "type": "string"
72
+ }
73
+ },
74
+ "required": [
75
+ "schema",
76
+ "subject",
77
+ "critic",
78
+ "decision"
79
+ ],
80
+ "additionalProperties": {}
81
+ }
@@ -411,6 +411,10 @@
411
411
  "area": {
412
412
  "type": "string"
413
413
  },
414
+ "kind": {
415
+ "description": "The kind of UI state the producer declared: `screen`, `overlay`, `loading`, `error`, `empty`… Open vocabulary",
416
+ "type": "string"
417
+ },
414
418
  "flags": {
415
419
  "type": "array",
416
420
  "items": {
@@ -468,6 +472,339 @@
468
472
  },
469
473
  "additionalProperties": {}
470
474
  },
475
+ "critique": {
476
+ "description": "Only for a check of a `critique` part whose `atlas.critique` extension can be read: the opinion of an automated reviewer. An opinion, never a result: it does not decide `status`, a slot or the gate. See the critics guide",
477
+ "type": "object",
478
+ "properties": {
479
+ "schema": {
480
+ "type": "integer",
481
+ "exclusiveMinimum": 0,
482
+ "maximum": 9007199254740991,
483
+ "description": "The version of this extension. 1"
484
+ },
485
+ "subject": {
486
+ "type": "object",
487
+ "properties": {
488
+ "entryKey": {
489
+ "type": "string",
490
+ "minLength": 1,
491
+ "description": "The catalog entry that was judged"
492
+ },
493
+ "imageSha256": {
494
+ "type": "string",
495
+ "minLength": 1,
496
+ "description": "The hash of the exact image bytes that were judged. When the entry's image changes, this critique judged an earlier image"
497
+ },
498
+ "state": {
499
+ "description": "The kind of UI state: `screen`, `overlay`, `loading`, `error`, `empty`…",
500
+ "type": "string",
501
+ "minLength": 1
502
+ }
503
+ },
504
+ "required": [
505
+ "entryKey",
506
+ "imageSha256"
507
+ ],
508
+ "additionalProperties": {}
509
+ },
510
+ "critic": {
511
+ "type": "object",
512
+ "properties": {
513
+ "name": {
514
+ "type": "string",
515
+ "minLength": 1
516
+ },
517
+ "version": {
518
+ "type": "string",
519
+ "minLength": 1,
520
+ "description": "Of the critic's own logic. A newer version replaces an older one"
521
+ },
522
+ "kind": {
523
+ "description": "Open vocabulary: `model`, `llm`, `ml`, `heuristic`…",
524
+ "type": "string",
525
+ "minLength": 1
526
+ }
527
+ },
528
+ "required": [
529
+ "name",
530
+ "version"
531
+ ],
532
+ "additionalProperties": {}
533
+ },
534
+ "model": {
535
+ "type": "object",
536
+ "properties": {
537
+ "id": {
538
+ "type": "string",
539
+ "minLength": 1
540
+ },
541
+ "provider": {
542
+ "type": "string"
543
+ }
544
+ },
545
+ "required": [
546
+ "id"
547
+ ],
548
+ "additionalProperties": {}
549
+ },
550
+ "parameters": {
551
+ "description": "Everything else that explains the result: temperature, seed, the SHA-256 of the rubric",
552
+ "type": "object",
553
+ "propertyNames": {
554
+ "type": "string"
555
+ },
556
+ "additionalProperties": {}
557
+ },
558
+ "verdict": {
559
+ "type": "object",
560
+ "properties": {
561
+ "score": {
562
+ "description": "A finite number. `scale` says what it means",
563
+ "type": "number"
564
+ },
565
+ "scale": {
566
+ "description": "For example `0..1, higher is better`",
567
+ "type": "string"
568
+ },
569
+ "label": {
570
+ "description": "Open vocabulary, conventionally `ok` or `needs-polish`",
571
+ "type": "string"
572
+ },
573
+ "confidence": {
574
+ "type": "number",
575
+ "minimum": 0,
576
+ "maximum": 1
577
+ },
578
+ "relative": {
579
+ "type": "object",
580
+ "properties": {
581
+ "stateKind": {
582
+ "type": "string",
583
+ "minLength": 1,
584
+ "description": "The kind of UI state the score is relative to: `screen`, `overlay`, `loading`, `error`, `empty`…"
585
+ },
586
+ "percentile": {
587
+ "description": "Where the score falls among the project's scores of the same state kind, 0..100, higher is better",
588
+ "type": "number",
589
+ "minimum": 0,
590
+ "maximum": 100
591
+ },
592
+ "sampleSize": {
593
+ "description": "How many scores of that state kind the percentile is over",
594
+ "type": "integer",
595
+ "minimum": 0,
596
+ "maximum": 9007199254740991
597
+ },
598
+ "previousScore": {
599
+ "description": "The same entry's score for its previous image, from the same critic",
600
+ "type": "number"
601
+ },
602
+ "delta": {
603
+ "description": "`score` minus `previousScore`",
604
+ "type": "number"
605
+ }
606
+ },
607
+ "required": [
608
+ "stateKind"
609
+ ],
610
+ "additionalProperties": {}
611
+ }
612
+ },
613
+ "additionalProperties": {}
614
+ },
615
+ "findings": {
616
+ "type": "array",
617
+ "items": {
618
+ "type": "object",
619
+ "properties": {
620
+ "id": {
621
+ "description": "Stable within the critique, so a reviewer can mark this finding valid or not",
622
+ "type": "string",
623
+ "minLength": 1
624
+ },
625
+ "category": {
626
+ "description": "Open vocabulary: `spacing`, `contrast`, `alignment`, `overflow`, `hierarchy`…",
627
+ "type": "string",
628
+ "minLength": 1
629
+ },
630
+ "severity": {
631
+ "description": "Open vocabulary, conventionally `info`, `minor`, `major`",
632
+ "type": "string",
633
+ "minLength": 1
634
+ },
635
+ "confidence": {
636
+ "type": "number",
637
+ "minimum": 0,
638
+ "maximum": 1
639
+ },
640
+ "region": {
641
+ "type": "object",
642
+ "properties": {
643
+ "unit": {
644
+ "type": "string",
645
+ "minLength": 1,
646
+ "description": "`px` (pixels of the stored image) or `normalized` (0..1 of its width and height). Open vocabulary"
647
+ },
648
+ "x": {
649
+ "type": "number"
650
+ },
651
+ "y": {
652
+ "type": "number"
653
+ },
654
+ "w": {
655
+ "type": "number",
656
+ "minimum": 0
657
+ },
658
+ "h": {
659
+ "type": "number",
660
+ "minimum": 0
661
+ }
662
+ },
663
+ "required": [
664
+ "unit",
665
+ "x",
666
+ "y",
667
+ "w",
668
+ "h"
669
+ ],
670
+ "additionalProperties": {}
671
+ },
672
+ "rationale": {
673
+ "type": "string"
674
+ },
675
+ "suggestion": {
676
+ "type": "string"
677
+ }
678
+ },
679
+ "additionalProperties": {}
680
+ }
681
+ },
682
+ "failure": {
683
+ "type": "object",
684
+ "properties": {
685
+ "reason": {
686
+ "type": "string",
687
+ "minLength": 1
688
+ },
689
+ "message": {
690
+ "type": "string"
691
+ }
692
+ },
693
+ "required": [
694
+ "reason"
695
+ ],
696
+ "additionalProperties": {}
697
+ },
698
+ "usage": {
699
+ "type": "object",
700
+ "properties": {
701
+ "inputTokens": {
702
+ "type": "number",
703
+ "minimum": 0
704
+ },
705
+ "outputTokens": {
706
+ "type": "number",
707
+ "minimum": 0
708
+ },
709
+ "latencyMs": {
710
+ "type": "number",
711
+ "minimum": 0
712
+ },
713
+ "costUsd": {
714
+ "type": "number",
715
+ "minimum": 0
716
+ }
717
+ },
718
+ "additionalProperties": {}
719
+ }
720
+ },
721
+ "required": [
722
+ "schema",
723
+ "subject",
724
+ "critic"
725
+ ],
726
+ "additionalProperties": {}
727
+ },
728
+ "critiqueMark": {
729
+ "description": "Only for a check of a `critique` part whose `atlas.critique-mark` extension can be read: a person's accept or dismiss of a critic's opinion. Evidence, never a result: it does not decide `status`, a slot or the gate. See the critics guide",
730
+ "type": "object",
731
+ "properties": {
732
+ "schema": {
733
+ "type": "integer",
734
+ "exclusiveMinimum": 0,
735
+ "maximum": 9007199254740991,
736
+ "description": "The version of this extension. 1"
737
+ },
738
+ "subject": {
739
+ "type": "object",
740
+ "properties": {
741
+ "entryKey": {
742
+ "type": "string",
743
+ "minLength": 1,
744
+ "description": "The catalog entry the marked critique is about"
745
+ },
746
+ "imageSha256": {
747
+ "type": "string",
748
+ "minLength": 1,
749
+ "description": "The hash of the picture the marked critique judged, so a mark about an earlier picture is shown as that"
750
+ }
751
+ },
752
+ "required": [
753
+ "entryKey",
754
+ "imageSha256"
755
+ ],
756
+ "additionalProperties": {}
757
+ },
758
+ "critic": {
759
+ "type": "object",
760
+ "properties": {
761
+ "name": {
762
+ "type": "string",
763
+ "minLength": 1
764
+ },
765
+ "version": {
766
+ "type": "string",
767
+ "minLength": 1
768
+ }
769
+ },
770
+ "required": [
771
+ "name"
772
+ ],
773
+ "additionalProperties": {},
774
+ "description": "The critic whose opinion is marked"
775
+ },
776
+ "finding": {
777
+ "description": "The `id` of the marked finding. Absent: the critique as a whole",
778
+ "type": "string",
779
+ "minLength": 1
780
+ },
781
+ "decision": {
782
+ "type": "string",
783
+ "minLength": 1,
784
+ "description": "Open vocabulary; this release understands `accept` (the opinion is right) and `dismiss` (it is not). Anything else is shown as written and counts as neither"
785
+ },
786
+ "reviewer": {
787
+ "description": "Who marked it: a name the reviewer chose, never an account",
788
+ "type": "string",
789
+ "minLength": 1
790
+ },
791
+ "note": {
792
+ "description": "Why, in the reviewer's words",
793
+ "type": "string"
794
+ },
795
+ "layer": {
796
+ "description": "The layer of the critique that was marked, for tracing",
797
+ "type": "string"
798
+ }
799
+ },
800
+ "required": [
801
+ "schema",
802
+ "subject",
803
+ "critic",
804
+ "decision"
805
+ ],
806
+ "additionalProperties": {}
807
+ },
471
808
  "recording": {
472
809
  "description": "What became of the check's expected recording: uploaded, referenced, skipped, unresolved or not-applicable. Independent of `status`",
473
810
  "type": "object",