@fuaran-ui/conformance 0.18.0 → 0.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.
Files changed (110) hide show
  1. package/corpus/cards/card-bundle.json +1 -0
  2. package/corpus/cards/card-full.json +1 -0
  3. package/corpus/cards/card-minimal.json +1 -0
  4. package/corpus/cards/card-reject-bad-version.json +1 -0
  5. package/corpus/cards/card-reject-bundle-bad-version.json +1 -0
  6. package/corpus/cards/card-reject-bundle-duplicate.json +1 -0
  7. package/corpus/cards/card-reject-empty-enum.json +1 -0
  8. package/corpus/cards/card-reject-hash-not-object.json +1 -0
  9. package/corpus/cards/card-reject-missing-hash.json +1 -0
  10. package/corpus/cards/card-reject-missing-module.json +1 -0
  11. package/corpus/cards/card-reject-payload-no-language.json +1 -0
  12. package/corpus/cards/card-reject-required-not-bool.json +1 -0
  13. package/corpus/cards/card-reject-stray-key.json +1 -0
  14. package/corpus/cards/card-reject-unknown-prop-type.json +1 -0
  15. package/corpus/lenient/lenient-1126-clipboard-literal-envelope.expected.json +1 -0
  16. package/corpus/lenient/lenient-1126-clipboard-literal-envelope.json +1 -0
  17. package/corpus/manifest.json +847 -3
  18. package/corpus/nodes/box-break-before-1.json +1 -0
  19. package/corpus/nodes/box-keep-together-1.json +1 -0
  20. package/corpus/nodes/btn-copy-bound.json +1 -0
  21. package/corpus/nodes/button-print.json +1 -0
  22. package/corpus/nodes/embed-1.json +1 -0
  23. package/corpus/nodes/embed-aspect-1.json +1 -0
  24. package/corpus/nodes/embed-permissions-1.json +1 -0
  25. package/corpus/nodes/filters-rating-colour.json +1 -0
  26. package/corpus/nodes/filters-tokens.json +1 -0
  27. package/corpus/nodes/form-color.json +1 -0
  28. package/corpus/nodes/form-combobox-freetext.json +1 -0
  29. package/corpus/nodes/form-combobox-query.json +1 -0
  30. package/corpus/nodes/form-combobox-static.json +1 -0
  31. package/corpus/nodes/form-rating-halves.json +1 -0
  32. package/corpus/nodes/form-rating.json +1 -0
  33. package/corpus/nodes/form-tokens-freetext.json +1 -0
  34. package/corpus/nodes/form-tokens-query.json +1 -0
  35. package/corpus/nodes/form-tokens-suggested.json +1 -0
  36. package/corpus/nodes/grid-exportable-1.json +1 -0
  37. package/corpus/nodes/grid-keep-rows-together-1.json +1 -0
  38. package/corpus/nodes/grid-repeat-header-1.json +1 -0
  39. package/corpus/nodes/limit-tree-item-depth-at-max.json +1 -0
  40. package/corpus/nodes/media-audio-transcript-1.json +1 -0
  41. package/corpus/nodes/media-video-captions-1.json +1 -0
  42. package/corpus/nodes/media-video-tracks-2.json +1 -0
  43. package/corpus/nodes/multiselect-chip-list-param.json +1 -0
  44. package/corpus/nodes/popover-anchored-1.json +1 -0
  45. package/corpus/nodes/popover-open-1.json +1 -0
  46. package/corpus/nodes/shared-source-seeded-pair.json +1 -1
  47. package/corpus/nodes/style-direction-isolated-1.json +1 -0
  48. package/corpus/nodes/style-direction-ltr-1.json +1 -0
  49. package/corpus/nodes/switch-carousel-1.json +1 -0
  50. package/corpus/nodes/tooltip-button-1.json +1 -0
  51. package/corpus/nodes/tooltip-icon-button-1.json +1 -0
  52. package/corpus/nodes/tooltip-metric-1.json +1 -0
  53. package/corpus/nodes/transfer-board.json +1 -0
  54. package/corpus/nodes/tree-1.json +1 -0
  55. package/corpus/nodes/tree-expanded-1.json +1 -0
  56. package/corpus/nodes/tree-selection-1.json +1 -0
  57. package/corpus/nodes/upload-capture-camera-1.json +1 -0
  58. package/corpus/nodes/upload-capture-microphone-1.json +1 -0
  59. package/corpus/nodes/upload-destination-1.json +1 -0
  60. package/corpus/nodes/upload-drop-1.json +1 -0
  61. package/corpus/nodes/upload-paste-1.json +1 -0
  62. package/corpus/ops/op-updatestyle (phase 1472 direction=ltr, the only style member).json +1 -0
  63. package/corpus/reject/reject-action-print-with-payload.json +1 -0
  64. package/corpus/reject/reject-color-value-not-hex.json +1 -0
  65. package/corpus/reject/reject-combobox-allowfreetext-nonbool.json +1 -0
  66. package/corpus/reject/reject-embed-missing-title.json +1 -0
  67. package/corpus/reject/reject-embed-permission-nonstring.json +1 -0
  68. package/corpus/reject/reject-embed-unknown-permission.json +1 -0
  69. package/corpus/reject/reject-limit-tree-item-depth.json +1 -0
  70. package/corpus/reject/reject-media-track-default-nonbool.json +1 -0
  71. package/corpus/reject/reject-media-track-missing-srclang.json +1 -0
  72. package/corpus/reject/reject-modal-modality-nonstring.json +1 -0
  73. package/corpus/reject/reject-modal-modality-unknown.json +1 -0
  74. package/corpus/reject/reject-op-updatestyle-direction-nonstring.json +1 -0
  75. package/corpus/reject/reject-op-updatestyle-direction-unknown.json +1 -0
  76. package/corpus/reject/reject-rating-max-zero.json +1 -0
  77. package/corpus/reject/reject-style-direction-nonstring.json +1 -0
  78. package/corpus/reject/reject-style-direction-unknown.json +1 -0
  79. package/corpus/reject/reject-switch-autoadvance-fractional.json +1 -0
  80. package/corpus/reject/reject-switch-autoadvance-negative.json +1 -0
  81. package/corpus/reject/reject-switch-autoadvance-zero.json +1 -0
  82. package/corpus/reject/reject-tokens-closed-without-suggestions.json +1 -0
  83. package/corpus/reject/reject-tokens-value-not-list.json +1 -0
  84. package/corpus/reject/reject-tooltip-nonstring.json +1 -0
  85. package/corpus/reject/reject-tree-item-missing-id.json +1 -0
  86. package/corpus/reject/reject-tree-item-missing-label.json +1 -0
  87. package/corpus/reject/reject-tree-nested-item-missing-id.json +1 -0
  88. package/corpus/reject/reject-unknown-capture-source.json +1 -0
  89. package/corpus/reject/reject-upload-acceptpaste-nonbool.json +1 -0
  90. package/corpus/reject/reject-upload-destination-empty.json +1 -0
  91. package/corpus/reject/reject-upload-droptarget-nonbool.json +1 -0
  92. package/corpus/reject/reject-wrongtype-box-break-before.json +1 -0
  93. package/corpus/reject/reject-wrongtype-box-keep-together.json +1 -0
  94. package/corpus/reject/reject-wrongtype-clipboard-payload.json +1 -0
  95. package/corpus/reject/reject-wrongtype-grid-exportable-number.json +1 -0
  96. package/corpus/reject/reject-wrongtype-grid-exportable.json +1 -0
  97. package/corpus/reject/reject-wrongtype-grid-keep-rows-together.json +1 -0
  98. package/corpus/reject/reject-wrongtype-grid-repeat-header.json +1 -0
  99. package/corpus/reject/reject-wrongtype-grid-transfer-in-key.json +1 -0
  100. package/corpus/reject/reject-wrongtype-grid-transfer-out-key.json +1 -0
  101. package/corpus/schema.json +333 -1
  102. package/dist/cli.js +94 -0
  103. package/dist/cli.js.map +1 -1
  104. package/dist/index.cjs +94 -0
  105. package/dist/index.cjs.map +1 -1
  106. package/dist/index.d.cts +18 -3
  107. package/dist/index.d.ts +18 -3
  108. package/dist/index.js +94 -0
  109. package/dist/index.js.map +1 -1
  110. package/package.json +3 -3
@@ -70,6 +70,15 @@
70
70
  "Contain"
71
71
  ]
72
72
  },
73
+ "TrackKind": {
74
+ "type": "string",
75
+ "enum": [
76
+ "Subtitles",
77
+ "Captions",
78
+ "Descriptions",
79
+ "Chapters"
80
+ ]
81
+ },
73
82
  "ImageAspect": {
74
83
  "type": "string",
75
84
  "enum": [
@@ -80,6 +89,15 @@
80
89
  "SixteenNine"
81
90
  ]
82
91
  },
92
+ "EmbedPermission": {
93
+ "type": "string",
94
+ "enum": [
95
+ "AllowScripts",
96
+ "AllowSameOrigin",
97
+ "AllowForms",
98
+ "AllowFullscreen"
99
+ ]
100
+ },
83
101
  "ImageLoading": {
84
102
  "type": "string",
85
103
  "enum": [
@@ -95,6 +113,20 @@
95
113
  "Both"
96
114
  ]
97
115
  },
116
+ "ModalityKind": {
117
+ "type": "string",
118
+ "enum": [
119
+ "Modal",
120
+ "Popover"
121
+ ]
122
+ },
123
+ "CaptureSource": {
124
+ "type": "string",
125
+ "enum": [
126
+ "Camera",
127
+ "Microphone"
128
+ ]
129
+ },
98
130
  "DateVariant": {
99
131
  "type": "string",
100
132
  "enum": [
@@ -182,6 +214,14 @@
182
214
  "Structural"
183
215
  ]
184
216
  },
217
+ "TextDirection": {
218
+ "type": "string",
219
+ "enum": [
220
+ "auto",
221
+ "ltr",
222
+ "rtl"
223
+ ]
224
+ },
185
225
  "ChartKind": {
186
226
  "type": "string",
187
227
  "enum": [
@@ -3301,7 +3341,7 @@
3301
3341
  "const": "WriteToClipboard"
3302
3342
  },
3303
3343
  "text": {
3304
- "type": "string"
3344
+ "$ref": "#/$defs/TextSource"
3305
3345
  }
3306
3346
  },
3307
3347
  "required": [
@@ -3353,6 +3393,18 @@
3353
3393
  "args",
3354
3394
  "capabilityId"
3355
3395
  ]
3396
+ },
3397
+ {
3398
+ "type": "object",
3399
+ "properties": {
3400
+ "$type": {
3401
+ "const": "Print"
3402
+ }
3403
+ },
3404
+ "required": [
3405
+ "$type"
3406
+ ],
3407
+ "additionalProperties": false
3356
3408
  }
3357
3409
  ]
3358
3410
  },
@@ -4093,6 +4145,94 @@
4093
4145
  "$type",
4094
4146
  "variant"
4095
4147
  ]
4148
+ },
4149
+ {
4150
+ "type": "object",
4151
+ "properties": {
4152
+ "$type": {
4153
+ "const": "Combobox"
4154
+ },
4155
+ "allowFreeText": {
4156
+ "type": "boolean"
4157
+ },
4158
+ "onChange": {
4159
+ "const": "<closure>"
4160
+ },
4161
+ "options": {
4162
+ "$ref": "#/$defs/Binding_list_SelectOption"
4163
+ },
4164
+ "value": {
4165
+ "$ref": "#/$defs/Binding_str"
4166
+ }
4167
+ },
4168
+ "required": [
4169
+ "$type",
4170
+ "options"
4171
+ ]
4172
+ },
4173
+ {
4174
+ "type": "object",
4175
+ "properties": {
4176
+ "$type": {
4177
+ "const": "Rating"
4178
+ },
4179
+ "allowHalf": {
4180
+ "type": "boolean"
4181
+ },
4182
+ "max": {
4183
+ "type": "integer"
4184
+ },
4185
+ "onChange": {
4186
+ "const": "<closure>"
4187
+ },
4188
+ "value": {
4189
+ "$ref": "#/$defs/Binding_float"
4190
+ }
4191
+ },
4192
+ "required": [
4193
+ "$type",
4194
+ "max"
4195
+ ]
4196
+ },
4197
+ {
4198
+ "type": "object",
4199
+ "properties": {
4200
+ "$type": {
4201
+ "const": "Color"
4202
+ },
4203
+ "onChange": {
4204
+ "const": "<closure>"
4205
+ },
4206
+ "value": {
4207
+ "$ref": "#/$defs/Binding_str"
4208
+ }
4209
+ },
4210
+ "required": [
4211
+ "$type"
4212
+ ]
4213
+ },
4214
+ {
4215
+ "type": "object",
4216
+ "properties": {
4217
+ "$type": {
4218
+ "const": "Tokens"
4219
+ },
4220
+ "allowFreeText": {
4221
+ "type": "boolean"
4222
+ },
4223
+ "onChange": {
4224
+ "const": "<closure>"
4225
+ },
4226
+ "suggestions": {
4227
+ "$ref": "#/$defs/Binding_list_SelectOption"
4228
+ },
4229
+ "value": {
4230
+ "$ref": "#/$defs/Binding_list_str"
4231
+ }
4232
+ },
4233
+ "required": [
4234
+ "$type"
4235
+ ]
4096
4236
  }
4097
4237
  ]
4098
4238
  },
@@ -4501,6 +4641,15 @@
4501
4641
  },
4502
4642
  "src": {
4503
4643
  "$ref": "#/$defs/Binding_str"
4644
+ },
4645
+ "tracks": {
4646
+ "type": "array",
4647
+ "items": {
4648
+ "$ref": "#/$defs/TrackEntry"
4649
+ }
4650
+ },
4651
+ "transcript": {
4652
+ "$ref": "#/$defs/TextSource"
4504
4653
  }
4505
4654
  },
4506
4655
  "required": [
@@ -4509,6 +4658,32 @@
4509
4658
  "src"
4510
4659
  ]
4511
4660
  },
4661
+ "TrackEntry": {
4662
+ "type": "object",
4663
+ "properties": {
4664
+ "default": {
4665
+ "type": "boolean"
4666
+ },
4667
+ "kind": {
4668
+ "$ref": "#/$defs/TrackKind"
4669
+ },
4670
+ "label": {
4671
+ "$ref": "#/$defs/TextSource"
4672
+ },
4673
+ "src": {
4674
+ "$ref": "#/$defs/Binding_str"
4675
+ },
4676
+ "srcLang": {
4677
+ "type": "string"
4678
+ }
4679
+ },
4680
+ "required": [
4681
+ "kind",
4682
+ "label",
4683
+ "src",
4684
+ "srcLang"
4685
+ ]
4686
+ },
4512
4687
  "MediaKind": {
4513
4688
  "oneOf": [
4514
4689
  {
@@ -4541,6 +4716,77 @@
4541
4716
  }
4542
4717
  ]
4543
4718
  },
4719
+ "EmbedSpec": {
4720
+ "type": "object",
4721
+ "properties": {
4722
+ "aspectRatio": {
4723
+ "$ref": "#/$defs/ImageAspect"
4724
+ },
4725
+ "permissions": {
4726
+ "type": "array",
4727
+ "items": {
4728
+ "$ref": "#/$defs/EmbedPermission"
4729
+ }
4730
+ },
4731
+ "src": {
4732
+ "$ref": "#/$defs/Binding_str"
4733
+ },
4734
+ "title": {
4735
+ "$ref": "#/$defs/TextSource"
4736
+ }
4737
+ },
4738
+ "required": [
4739
+ "src",
4740
+ "title"
4741
+ ]
4742
+ },
4743
+ "TreeItem": {
4744
+ "type": "object",
4745
+ "properties": {
4746
+ "children": {
4747
+ "type": "array",
4748
+ "items": {
4749
+ "$ref": "#/$defs/TreeItem"
4750
+ }
4751
+ },
4752
+ "icon": {
4753
+ "type": "string"
4754
+ },
4755
+ "id": {
4756
+ "type": "string"
4757
+ },
4758
+ "label": {
4759
+ "$ref": "#/$defs/TextSource"
4760
+ }
4761
+ },
4762
+ "required": [
4763
+ "id",
4764
+ "label"
4765
+ ]
4766
+ },
4767
+ "TreeSpec": {
4768
+ "type": "object",
4769
+ "properties": {
4770
+ "expandedStateKey": {
4771
+ "type": "string"
4772
+ },
4773
+ "items": {
4774
+ "type": "array",
4775
+ "items": {
4776
+ "$ref": "#/$defs/TreeItem"
4777
+ }
4778
+ },
4779
+ "onSelect": {
4780
+ "const": "<closure>"
4781
+ },
4782
+ "selectionStateKey": {
4783
+ "type": "string"
4784
+ }
4785
+ },
4786
+ "required": [
4787
+ "items"
4788
+ ]
4789
+ },
4544
4790
  "ListSpec": {
4545
4791
  "type": "object",
4546
4792
  "properties": {
@@ -5745,6 +5991,42 @@
5745
5991
  }
5746
5992
  ]
5747
5993
  },
5994
+ {
5995
+ "allOf": [
5996
+ {
5997
+ "type": "object",
5998
+ "properties": {
5999
+ "$type": {
6000
+ "const": "Embed"
6001
+ }
6002
+ },
6003
+ "required": [
6004
+ "$type"
6005
+ ]
6006
+ },
6007
+ {
6008
+ "$ref": "#/$defs/EmbedSpec"
6009
+ }
6010
+ ]
6011
+ },
6012
+ {
6013
+ "allOf": [
6014
+ {
6015
+ "type": "object",
6016
+ "properties": {
6017
+ "$type": {
6018
+ "const": "Tree"
6019
+ }
6020
+ },
6021
+ "required": [
6022
+ "$type"
6023
+ ]
6024
+ },
6025
+ {
6026
+ "$ref": "#/$defs/TreeSpec"
6027
+ }
6028
+ ]
6029
+ },
5748
6030
  {
5749
6031
  "allOf": [
5750
6032
  {
@@ -6095,6 +6377,19 @@
6095
6377
  },
6096
6378
  "disabled": {
6097
6379
  "$ref": "#/$defs/Binding_bool"
6380
+ },
6381
+ "dropTarget": {
6382
+ "type": "boolean"
6383
+ },
6384
+ "acceptPaste": {
6385
+ "type": "boolean"
6386
+ },
6387
+ "capture": {
6388
+ "$ref": "#/$defs/CaptureSource"
6389
+ },
6390
+ "destination": {
6391
+ "type": "string",
6392
+ "minLength": 1
6098
6393
  }
6099
6394
  },
6100
6395
  "required": [
@@ -6274,6 +6569,21 @@
6274
6569
  "reorderable": {
6275
6570
  "type": "boolean"
6276
6571
  },
6572
+ "transferInKey": {
6573
+ "type": "string"
6574
+ },
6575
+ "transferOutKey": {
6576
+ "type": "string"
6577
+ },
6578
+ "keepRowsTogether": {
6579
+ "type": "boolean"
6580
+ },
6581
+ "repeatHeader": {
6582
+ "type": "boolean"
6583
+ },
6584
+ "exportable": {
6585
+ "type": "boolean"
6586
+ },
6277
6587
  "defaultSort": {
6278
6588
  "type": "object",
6279
6589
  "properties": {
@@ -6630,6 +6940,12 @@
6630
6940
  "Dashboard",
6631
6941
  "Separator"
6632
6942
  ]
6943
+ },
6944
+ "keepTogether": {
6945
+ "type": "boolean"
6946
+ },
6947
+ "breakBefore": {
6948
+ "type": "boolean"
6633
6949
  }
6634
6950
  },
6635
6951
  "required": [
@@ -6931,6 +7247,12 @@
6931
7247
  },
6932
7248
  "heading": {
6933
7249
  "$ref": "#/$defs/TextSource"
7250
+ },
7251
+ "modality": {
7252
+ "$ref": "#/$defs/ModalityKind"
7253
+ },
7254
+ "anchor": {
7255
+ "type": "string"
6934
7256
  }
6935
7257
  },
6936
7258
  "required": [
@@ -7618,6 +7940,10 @@
7618
7940
  },
7619
7941
  "on": {
7620
7942
  "$ref": "#/$defs/Binding_str"
7943
+ },
7944
+ "autoAdvanceMs": {
7945
+ "type": "integer",
7946
+ "minimum": 1
7621
7947
  }
7622
7948
  },
7623
7949
  "required": [
@@ -7760,6 +8086,9 @@
7760
8086
  },
7761
8087
  "voice": {
7762
8088
  "$ref": "#/$defs/FontVoice"
8089
+ },
8090
+ "direction": {
8091
+ "$ref": "#/$defs/TextDirection"
7763
8092
  }
7764
8093
  }
7765
8094
  },
@@ -7918,6 +8247,9 @@
7918
8247
  },
7919
8248
  "accessibility": {
7920
8249
  "$ref": "#/$defs/Accessibility"
8250
+ },
8251
+ "tooltip": {
8252
+ "$ref": "#/$defs/TextSource"
7921
8253
  }
7922
8254
  },
7923
8255
  "required": [
package/dist/cli.js CHANGED
@@ -446,6 +446,85 @@ var runConformance = (adapter2, options) => {
446
446
  a.passed++;
447
447
  }
448
448
  }
449
+ const roundTripContractCard = adapter2.roundTripContractCard;
450
+ if (roundTripContractCard !== void 0) {
451
+ const cardDecoder = (f) => f.decoder === "contract-card-bundle" ? "contract-card-bundle" : "contract-card";
452
+ for (const f of corpus.fixtures.filter((x) => x.kind === "contract-card-round-trip")) {
453
+ const a = acc("contract-card-round-trip");
454
+ a.total++;
455
+ const input = corpus.read(f.inputFile);
456
+ let r;
457
+ try {
458
+ r = roundTripContractCard(cardDecoder(f), input);
459
+ } catch (err) {
460
+ a.failures.push({
461
+ fixtureId: f.id,
462
+ summary: "roundTripContractCard THREW on a round-trip fixture (must return a structured result)",
463
+ detail: messageOf(err)
464
+ });
465
+ continue;
466
+ }
467
+ if (!r.ok) {
468
+ a.failures.push({
469
+ fixtureId: f.id,
470
+ summary: "roundTripContractCard refused a round-trip fixture",
471
+ detail: `${r.error.code} at ${r.error.path}`
472
+ });
473
+ continue;
474
+ }
475
+ const expected = canon(corpus.read(f.expectedFile ?? f.inputFile));
476
+ if (typeof r.value !== "string" || r.value !== expected) {
477
+ a.failures.push({
478
+ fixtureId: f.id,
479
+ summary: "card re-encode diverges from the canonical form",
480
+ detail: typeof r.value === "string" ? firstDiff(expected, r.value) : "value was not a string"
481
+ });
482
+ continue;
483
+ }
484
+ a.passed++;
485
+ }
486
+ for (const f of corpus.fixtures.filter((x) => x.kind === "contract-card-reject")) {
487
+ const a = acc("contract-card-reject");
488
+ a.total++;
489
+ const input = corpus.read(f.inputFile);
490
+ let r;
491
+ try {
492
+ r = roundTripContractCard(cardDecoder(f), input);
493
+ } catch (err) {
494
+ a.failures.push({
495
+ fixtureId: f.id,
496
+ summary: "roundTripContractCard THREW on a reject fixture (must return a structured error)",
497
+ detail: messageOf(err)
498
+ });
499
+ continue;
500
+ }
501
+ if (r.ok) {
502
+ a.failures.push({
503
+ fixtureId: f.id,
504
+ summary: "roundTripContractCard ACCEPTED a reject fixture",
505
+ detail: `expected ${f.expectedErrorCode} at ${f.expectedPath}`
506
+ });
507
+ continue;
508
+ }
509
+ if (r.error.code !== f.expectedErrorCode) {
510
+ a.failures.push({
511
+ fixtureId: f.id,
512
+ summary: "refusal CODE diverges from the canonical error",
513
+ detail: `expected ${f.expectedErrorCode}, got ${r.error.code} (path ${r.error.path})`
514
+ });
515
+ continue;
516
+ }
517
+ if (!r.error.path.startsWith(f.expectedPath ?? "$")) {
518
+ a.failures.push({
519
+ fixtureId: f.id,
520
+ summary: "refusal PATH diverges from the canonical error",
521
+ detail: `expected prefix ${f.expectedPath}, got ${r.error.path}`
522
+ });
523
+ continue;
524
+ }
525
+ a.passed++;
526
+ }
527
+ }
449
528
  const validateAnswerDocument = adapter2.validateAnswerDocument;
450
529
  if (validateAnswerDocument !== void 0) {
451
530
  for (const f of corpus.fixtures.filter(
@@ -555,6 +634,21 @@ var runConformance = (adapter2, options) => {
555
634
  accs.get("schema-validation"),
556
635
  hasSchemaInput ? need(["a decode hook for the encode hooks provided"]) : need(["encodeNode and/or encodeOp"])
557
636
  ),
637
+ // NOT mandatory — see the `roundTripContractCard` doc comment: §25 adoption
638
+ // is a separate bar from wire conformance, so a byte-perfect host that holds
639
+ // no card reader must not be reported non-conformant for it.
640
+ toLeg(
641
+ "contract-card-round-trip",
642
+ false,
643
+ accs.get("contract-card-round-trip"),
644
+ need(["roundTripContractCard"])
645
+ ),
646
+ toLeg(
647
+ "contract-card-reject",
648
+ false,
649
+ accs.get("contract-card-reject"),
650
+ need(["roundTripContractCard"])
651
+ ),
558
652
  toLeg("apply", false, void 0, "corpus v1 ships no apply fixtures \u2014 leg reserved")
559
653
  ];
560
654
  return {