Viewing is open to everyone. Downloading and starring need a GitHub sign-in. Sign in with GitHub

suite.json

v0.1.0-build.85 Latest Commit ede38f5

Size
28 KB
Lines
910
Language
json
SHA-256
4df93be3f475…
View on GitHub

Sign in with GitHub to download. Each download is recorded with your GitHub username.

1{
2 "schema": 1,
3 "suite_version": "1.0",
4 "title": "CKey field tests",
5 "summary": "Repeatable checks of how CKey reads in the real world: printed sizes, distance, angle, light, screens, damage, styles, density, small labels, speed and payload safety. Each test states the claim it checks, how to set it up, what to record, and how to grade the result.",
6 "results_url": "https://openckey.org/tests",
7 "results_json": "https://openckey.org/api/field/results",
8 "report_on_github": "https://github.com/clearkeysolutions/ckey/issues/new?template=field-test-report.yml",
9 "environment": [
10 {
11 "id": "device",
12 "label": "Phone, tablet or camera",
13 "type": "text",
14 "required": true,
15 "help": "Model, for example iPhone 15 or Pixel 8a."
16 },
17 {
18 "id": "os",
19 "label": "Operating system and version",
20 "type": "text",
21 "required": true
22 },
23 {
24 "id": "reader",
25 "label": "Reader",
26 "type": "choice",
27 "required": true,
28 "options": [
29 "Open CKey Scanner (iOS)",
30 "openckey.org scanner (web)",
31 "An app built with a CKey SDK",
32 "Other"
33 ]
34 },
35 {
36 "id": "reader_version",
37 "label": "Reader version",
38 "type": "text",
39 "required": false,
40 "help": "Shown in the app's Settings, or the SDK version."
41 },
42 {
43 "id": "medium",
44 "label": "Printer, paper or screen",
45 "type": "text",
46 "required": false,
47 "help": "For example: laser printer on plain paper, or a laptop screen."
48 }
49 ],
50 "outcomes": {
51 "pass": "Meets the pass criterion in the test's rubric.",
52 "partial": "Meets the partial criterion but not the pass criterion.",
53 "fail": "Meets neither."
54 },
55 "styles": {
56 "plain": {
57 "description": "The default: black on white.",
58 "ckey_style": {}
59 },
60 "concept": {
61 "description": "The core's Concept preset.",
62 "preset": "concept",
63 "ckey_style": {}
64 },
65 "dark": {
66 "description": "Paper-coloured ink on an ink-coloured background.",
67 "ckey_style": {
68 "ink": "#FCFAF6",
69 "background": "#18211A"
70 }
71 },
72 "accents": {
73 "description": "35% of the data marks in two accent colours.",
74 "ckey_style": {
75 "accents": [
76 "#9A3130",
77 "#215D3B"
78 ],
79 "accent_percent": 35
80 }
81 },
82 "dots": {
83 "description": "Dotted rings, circle modules and flat ray caps in navy.",
84 "ckey_style": {
85 "rings": "dots",
86 "modules": "circle",
87 "rays": "flat",
88 "ink": "#1C2B4A"
89 }
90 }
91 },
92 "tests": [
93 {
94 "id": "FT-01",
95 "title": "Smallest printed size",
96 "category": "Print",
97 "claim": "A standard-layout CKey holding a short link reads when printed at 1 inch (25 mm) wide.",
98 "rationale": "Print size is the first thing a designer chooses and the easiest mistake to make. The core's certification models camera photos down to a few pixels per module; this test checks that model against real printers and real cameras.",
99 "time_minutes": 10,
100 "setup": [
101 "Print the test sheet at 100% scale (no \"fit to page\") on plain white paper.",
102 "Measure code F with a ruler: it must be 2.0 inches (51 mm) wide. If it is not, your printer scaled the sheet; fix the print settings and print again.",
103 "Hold the phone about 20 cm from the sheet in ordinary indoor light."
104 ],
105 "steps": [
106 "Open the reader.",
107 "Point it at each code from A (smallest) to F (largest), one at a time, for up to 5 seconds each.",
108 "Record whether it read and roughly how many seconds it took."
109 ],
110 "codes": [
111 {
112 "label": "A",
113 "payload": "https://openckey.org/t/FT01-A",
114 "level": "M",
115 "layout": "standard",
116 "style": "plain",
117 "size_in": 0.4
118 },
119 {
120 "label": "B",
121 "payload": "https://openckey.org/t/FT01-B",
122 "level": "M",
123 "layout": "standard",
124 "style": "plain",
125 "size_in": 0.5
126 },
127 {
128 "label": "C",
129 "payload": "https://openckey.org/t/FT01-C",
130 "level": "M",
131 "layout": "standard",
132 "style": "plain",
133 "size_in": 0.75
134 },
135 {
136 "label": "D",
137 "payload": "https://openckey.org/t/FT01-D",
138 "level": "M",
139 "layout": "standard",
140 "style": "plain",
141 "size_in": 1.0
142 },
143 {
144 "label": "E",
145 "payload": "https://openckey.org/t/FT01-E",
146 "level": "M",
147 "layout": "standard",
148 "style": "plain",
149 "size_in": 1.5
150 },
151 {
152 "label": "F",
153 "payload": "https://openckey.org/t/FT01-F",
154 "level": "M",
155 "layout": "standard",
156 "style": "plain",
157 "size_in": 2.0
158 }
159 ],
160 "measurements": [
161 {
162 "id": "read",
163 "label": "Read within 5 seconds",
164 "type": "boolean",
165 "trials": [
166 "A",
167 "B",
168 "C",
169 "D",
170 "E",
171 "F"
172 ],
173 "required": true
174 },
175 {
176 "id": "seconds",
177 "label": "Seconds to read",
178 "type": "number",
179 "unit": "s",
180 "min": 0,
181 "max": 30,
182 "trials": [
183 "A",
184 "B",
185 "C",
186 "D",
187 "E",
188 "F"
189 ],
190 "required": false
191 }
192 ],
193 "rubric": {
194 "pass": "Code D (1 inch) and every larger code read.",
195 "partial": "Only code E (1.5 inches) or larger read.",
196 "fail": "Code F (2 inches) did not read."
197 }
198 },
199 {
200 "id": "FT-02",
201 "title": "Reading distance",
202 "category": "Distance",
203 "claim": "A 2-inch CKey reads from arm's length, about 60 cm.",
204 "rationale": "Posters, shelf labels and screens are read from further away than a business card. Distance shrinks the code in the image exactly as print size does, so this shows how far the size results stretch.",
205 "time_minutes": 10,
206 "setup": [
207 "Print the test sheet at 100% scale and check that the code is 2.0 inches (51 mm) wide.",
208 "Tape it to a wall at eye level in even indoor light.",
209 "Mark distances of 15, 30, 60, 100 and 150 cm from the wall."
210 ],
211 "steps": [
212 "Stand at each distance in turn, holding the phone square to the sheet.",
213 "Allow up to 5 seconds at each distance without zooming.",
214 "Record whether it read."
215 ],
216 "codes": [
217 {
218 "label": "A",
219 "payload": "https://openckey.org/t/FT02-A",
220 "level": "M",
221 "layout": "standard",
222 "style": "plain",
223 "size_in": 2.0
224 }
225 ],
226 "measurements": [
227 {
228 "id": "read",
229 "label": "Read within 5 seconds",
230 "type": "boolean",
231 "trials": [
232 "15 cm",
233 "30 cm",
234 "60 cm",
235 "100 cm",
236 "150 cm"
237 ],
238 "required": true
239 }
240 ],
241 "rubric": {
242 "pass": "It read at 15, 30 and 60 cm.",
243 "partial": "It read at 15 and 30 cm but not at 60 cm.",
244 "fail": "It did not read at 30 cm."
245 }
246 },
247 {
248 "id": "FT-03",
249 "title": "Viewing angle",
250 "category": "Angle",
251 "claim": "A CKey reads when seen at up to 45 degrees off square.",
252 "rationale": "People rarely hold a phone square to a label. The frame and four corner finders exist to undo perspective; this checks how far they stretch.",
253 "time_minutes": 10,
254 "setup": [
255 "Print the test sheet at 100% scale; the code is 2.0 inches wide.",
256 "Lay it flat on a table in even light.",
257 "Hold the phone about 30 cm away."
258 ],
259 "steps": [
260 "Start square above the code (0 degrees), then tilt the phone to roughly 30, 45, 60 and 70 degrees from straight down, keeping the code centred.",
261 "Allow up to 5 seconds at each angle.",
262 "Record whether it read. A protractor app helps but an estimate is fine."
263 ],
264 "codes": [
265 {
266 "label": "A",
267 "payload": "https://openckey.org/t/FT03-A",
268 "level": "M",
269 "layout": "standard",
270 "style": "plain",
271 "size_in": 2.0
272 }
273 ],
274 "measurements": [
275 {
276 "id": "read",
277 "label": "Read within 5 seconds",
278 "type": "boolean",
279 "trials": [
280 "0°",
281 "30°",
282 "45°",
283 "60°",
284 "70°"
285 ],
286 "required": true
287 }
288 ],
289 "rubric": {
290 "pass": "It read at 0, 30 and 45 degrees.",
291 "partial": "It read at 0 and 30 degrees but not at 45.",
292 "fail": "It did not read at 30 degrees."
293 }
294 },
295 {
296 "id": "FT-04",
297 "title": "Lighting",
298 "category": "Light",
299 "claim": "A printed CKey reads in daylight, ordinary indoor light, dim light and under a reflection.",
300 "rationale": "Low light adds noise and blur, warm light shifts colour, and glare washes out part of the code. The certification model includes noise and glare; this checks it against real rooms.",
301 "time_minutes": 15,
302 "setup": [
303 "Print the test sheet at 100% scale; the code is 2.0 inches wide.",
304 "Keep the phone about 25 cm from the sheet with the flash off."
305 ],
306 "steps": [
307 "Try the code in each condition: outdoor daylight (not direct sun on the screen), ordinary indoor light, a dim room lit by one distant lamp, warm lamp light close by, and with a bright reflection crossing part of the code (glossy paper or a sheet protector under a lamp).",
308 "Allow up to 5 seconds in each.",
309 "Record whether it read, and optionally the light level from a light-meter app."
310 ],
311 "codes": [
312 {
313 "label": "A",
314 "payload": "https://openckey.org/t/FT04-A",
315 "level": "M",
316 "layout": "standard",
317 "style": "plain",
318 "size_in": 2.0
319 }
320 ],
321 "measurements": [
322 {
323 "id": "read",
324 "label": "Read within 5 seconds",
325 "type": "boolean",
326 "trials": [
327 "Daylight",
328 "Indoor",
329 "Dim",
330 "Warm lamp",
331 "Reflection"
332 ],
333 "required": true
334 },
335 {
336 "id": "lux",
337 "label": "Light level, if measured",
338 "type": "number",
339 "unit": "lux",
340 "min": 0,
341 "max": 200000,
342 "trials": [
343 "Daylight",
344 "Indoor",
345 "Dim",
346 "Warm lamp",
347 "Reflection"
348 ],
349 "required": false
350 }
351 ],
352 "rubric": {
353 "pass": "It read in daylight, indoor, dim and warm light.",
354 "partial": "It read in daylight and indoor light only.",
355 "fail": "It did not read in ordinary indoor light."
356 }
357 },
358 {
359 "id": "FT-05",
360 "title": "On a screen",
361 "category": "Screen",
362 "claim": "A CKey shown on a phone or computer screen reads, including at low brightness and in light-on-dark colours.",
363 "rationale": "Many codes are read off another screen: a ticket in a wallet app, a slide, a monitor. Screens add moiré, refresh banding and glare that paper does not.",
364 "time_minutes": 10,
365 "setup": [
366 "Open this test's sheet on a second device: another phone, a tablet or a computer.",
367 "Make each code about 2 inches (5 cm) wide on that screen."
368 ],
369 "steps": [
370 "Try code A (black on white) at full brightness, then at the lowest comfortable brightness.",
371 "Try code B (light on dark) at full brightness.",
372 "Try code A on a computer monitor at arm's length.",
373 "Allow up to 5 seconds each and record whether it read."
374 ],
375 "codes": [
376 {
377 "label": "A",
378 "payload": "https://openckey.org/t/FT05-A",
379 "level": "M",
380 "layout": "standard",
381 "style": "plain",
382 "size_in": 2.0
383 },
384 {
385 "label": "B",
386 "payload": "https://openckey.org/t/FT05-B",
387 "level": "M",
388 "layout": "standard",
389 "style": "dark",
390 "size_in": 2.0
391 }
392 ],
393 "measurements": [
394 {
395 "id": "read",
396 "label": "Read within 5 seconds",
397 "type": "boolean",
398 "trials": [
399 "A, full brightness",
400 "A, low brightness",
401 "B, full brightness",
402 "A, monitor"
403 ],
404 "required": true
405 }
406 ],
407 "rubric": {
408 "pass": "Every case read.",
409 "partial": "Code A at full brightness read, but another case did not.",
410 "fail": "Code A at full brightness did not read."
411 }
412 },
413 {
414 "id": "FT-06",
415 "title": "Damage",
416 "category": "Damage",
417 "claim": "Error correction lets a CKey read through marks, a covered patch and creasing, with more damage tolerated at higher levels.",
418 "rationale": "Reed–Solomon correction and the scrambled layout are meant to spread damage thinly across many bytes. This is the plainest way to see whether level H buys what it costs.",
419 "time_minutes": 20,
420 "setup": [
421 "Print the test sheet twice at 100% scale; each code is 2.0 inches wide. Code A is level M and code B is level H.",
422 "Keep the first copy clean for comparison."
423 ],
424 "steps": [
425 "On the second copy, damage both codes the same way, one step at a time, testing after each step:",
426 "1. Draw one pen line, about 2 mm wide, straight across the middle.",
427 "2. Cover the bottom-right corner area with a sticky note about 1/8 of the code's width.",
428 "3. Crumple the sheet into a ball, then flatten it.",
429 "Allow up to 5 seconds each and record whether each code read."
430 ],
431 "codes": [
432 {
433 "label": "A",
434 "payload": "https://openckey.org/t/FT06-A",
435 "level": "M",
436 "layout": "standard",
437 "style": "plain",
438 "size_in": 2.0
439 },
440 {
441 "label": "B",
442 "payload": "https://openckey.org/t/FT06-B",
443 "level": "H",
444 "layout": "standard",
445 "style": "plain",
446 "size_in": 2.0
447 }
448 ],
449 "measurements": [
450 {
451 "id": "read_m",
452 "label": "Code A (level M) read",
453 "type": "boolean",
454 "trials": [
455 "Clean",
456 "Pen line",
457 "Covered corner",
458 "Crumpled"
459 ],
460 "required": true
461 },
462 {
463 "id": "read_h",
464 "label": "Code B (level H) read",
465 "type": "boolean",
466 "trials": [
467 "Clean",
468 "Pen line",
469 "Covered corner",
470 "Crumpled"
471 ],
472 "required": true
473 }
474 ],
475 "rubric": {
476 "pass": "Code B read after every step.",
477 "partial": "Both read clean and after the pen line, but code B failed a later step.",
478 "fail": "Code B did not read after the pen line."
479 }
480 },
481 {
482 "id": "FT-07",
483 "title": "Styles in the real world",
484 "category": "Design",
485 "claim": "A style the core certifies reads in practice, and reads about as well as plain black on white.",
486 "rationale": "Certification photographs each style in a model before it is allowed. This is the check that the model's verdict holds on real paper and real cameras, style by style.",
487 "time_minutes": 15,
488 "setup": [
489 "Print the test sheet in colour at 100% scale; each code is 1.5 inches wide.",
490 "Use ordinary indoor light and hold the phone about 20 cm away."
491 ],
492 "steps": [
493 "Try each code, A to E, for up to 5 seconds.",
494 "Record whether it read and roughly how many seconds it took.",
495 "Note anything about a style that seemed harder, such as needing to move closer."
496 ],
497 "codes": [
498 {
499 "label": "A",
500 "payload": "https://openckey.org/t/FT07-A",
501 "level": "M",
502 "layout": "standard",
503 "style": "plain",
504 "size_in": 1.5
505 },
506 {
507 "label": "B",
508 "payload": "https://openckey.org/t/FT07-B",
509 "level": "Q",
510 "layout": "standard",
511 "style": "concept",
512 "size_in": 1.5
513 },
514 {
515 "label": "C",
516 "payload": "https://openckey.org/t/FT07-C",
517 "level": "M",
518 "layout": "standard",
519 "style": "dark",
520 "size_in": 1.5
521 },
522 {
523 "label": "D",
524 "payload": "https://openckey.org/t/FT07-D",
525 "level": "M",
526 "layout": "standard",
527 "style": "accents",
528 "size_in": 1.5
529 },
530 {
531 "label": "E",
532 "payload": "https://openckey.org/t/FT07-E",
533 "level": "M",
534 "layout": "standard",
535 "style": "dots",
536 "size_in": 1.5
537 }
538 ],
539 "measurements": [
540 {
541 "id": "read",
542 "label": "Read within 5 seconds",
543 "type": "boolean",
544 "trials": [
545 "A plain",
546 "B concept",
547 "C dark",
548 "D accents",
549 "E dots"
550 ],
551 "required": true
552 },
553 {
554 "id": "seconds",
555 "label": "Seconds to read",
556 "type": "number",
557 "unit": "s",
558 "min": 0,
559 "max": 30,
560 "trials": [
561 "A plain",
562 "B concept",
563 "C dark",
564 "D accents",
565 "E dots"
566 ],
567 "required": false
568 }
569 ],
570 "rubric": {
571 "pass": "Every style read.",
572 "partial": "The plain code and at least three styles read.",
573 "fail": "The plain code read but two or more styles did not."
574 }
575 },
576 {
577 "id": "FT-08",
578 "title": "Density",
579 "category": "Capacity",
580 "claim": "At a fixed 2-inch print size, denser versions need a closer, steadier camera; version 10 still reads.",
581 "rationale": "More data means smaller marks at the same size. This shows where, for an ordinary phone, a code should be printed larger to carry more.",
582 "time_minutes": 10,
583 "setup": [
584 "Print the test sheet at 100% scale; each code is 2.0 inches wide.",
585 "Use ordinary indoor light."
586 ],
587 "steps": [
588 "Try each code, A (version 1) to E (version 20), from about 20 cm, moving closer if needed.",
589 "Allow up to 8 seconds each.",
590 "Record whether it read and the closest distance you needed."
591 ],
592 "codes": [
593 {
594 "label": "A",
595 "payload": "https://openckey.org/t/FT08-A",
596 "version": 1,
597 "level": "L",
598 "layout": "standard",
599 "style": "plain",
600 "size_in": 2.0
601 },
602 {
603 "label": "B",
604 "payload": "https://openckey.org/t/FT08-B",
605 "version": 5,
606 "level": "M",
607 "layout": "standard",
608 "style": "plain",
609 "size_in": 2.0
610 },
611 {
612 "label": "C",
613 "payload": "https://openckey.org/t/FT08-C",
614 "version": 10,
615 "level": "M",
616 "layout": "standard",
617 "style": "plain",
618 "size_in": 2.0
619 },
620 {
621 "label": "D",
622 "payload": "https://openckey.org/t/FT08-D",
623 "version": 15,
624 "level": "M",
625 "layout": "standard",
626 "style": "plain",
627 "size_in": 2.0
628 },
629 {
630 "label": "E",
631 "payload": "https://openckey.org/t/FT08-E",
632 "version": 20,
633 "level": "M",
634 "layout": "standard",
635 "style": "plain",
636 "size_in": 2.0
637 }
638 ],
639 "measurements": [
640 {
641 "id": "read",
642 "label": "Read within 8 seconds",
643 "type": "boolean",
644 "trials": [
645 "v1",
646 "v5",
647 "v10",
648 "v15",
649 "v20"
650 ],
651 "required": true
652 },
653 {
654 "id": "distance",
655 "label": "Distance needed",
656 "type": "number",
657 "unit": "cm",
658 "min": 0,
659 "max": 200,
660 "trials": [
661 "v1",
662 "v5",
663 "v10",
664 "v15",
665 "v20"
666 ],
667 "required": false
668 }
669 ],
670 "rubric": {
671 "pass": "Versions 1, 5 and 10 read.",
672 "partial": "Versions 1 and 5 read but not 10.",
673 "fail": "Version 5 did not read."
674 }
675 },
676 {
677 "id": "FT-09",
678 "title": "Small labels: print layout",
679 "category": "Print",
680 "claim": "The print layout (Profile 0.1) reads at smaller sizes than the standard layout.",
681 "rationale": "The print layout uses larger marks and gaps for small labels, so a printer's dot gain and a camera's blur do not close the gaps. This checks that it earns its place.",
682 "time_minutes": 15,
683 "setup": [
684 "Print the test sheet at 100% scale on the best printer you have, ideally 600 dpi.",
685 "Codes A to C use the standard layout; D to F use the print layout, at the same three sizes."
686 ],
687 "steps": [
688 "From as close as your phone can focus, try each code for up to 8 seconds.",
689 "Record whether it read."
690 ],
691 "codes": [
692 {
693 "label": "A",
694 "payload": "https://openckey.org/t/FT09-A",
695 "level": "M",
696 "layout": "standard",
697 "style": "plain",
698 "size_in": 0.3
699 },
700 {
701 "label": "B",
702 "payload": "https://openckey.org/t/FT09-B",
703 "level": "M",
704 "layout": "standard",
705 "style": "plain",
706 "size_in": 0.4
707 },
708 {
709 "label": "C",
710 "payload": "https://openckey.org/t/FT09-C",
711 "level": "M",
712 "layout": "standard",
713 "style": "plain",
714 "size_in": 0.5
715 },
716 {
717 "label": "D",
718 "payload": "https://openckey.org/t/FT09-D",
719 "level": "M",
720 "layout": "print",
721 "style": "plain",
722 "size_in": 0.3
723 },
724 {
725 "label": "E",
726 "payload": "https://openckey.org/t/FT09-E",
727 "level": "M",
728 "layout": "print",
729 "style": "plain",
730 "size_in": 0.4
731 },
732 {
733 "label": "F",
734 "payload": "https://openckey.org/t/FT09-F",
735 "level": "M",
736 "layout": "print",
737 "style": "plain",
738 "size_in": 0.5
739 }
740 ],
741 "measurements": [
742 {
743 "id": "read",
744 "label": "Read within 8 seconds",
745 "type": "boolean",
746 "trials": [
747 "A std 0.3 in",
748 "B std 0.4 in",
749 "C std 0.5 in",
750 "D print 0.3 in",
751 "E print 0.4 in",
752 "F print 0.5 in"
753 ],
754 "required": true
755 },
756 {
757 "id": "dpi",
758 "label": "Printer resolution",
759 "type": "number",
760 "unit": "dpi",
761 "min": 72,
762 "max": 4800,
763 "required": false
764 }
765 ],
766 "rubric": {
767 "pass": "A print-layout code read at a size where the standard layout did not.",
768 "partial": "Both layouts read at the same sizes.",
769 "fail": "The print layout read at no size where the standard layout read."
770 }
771 },
772 {
773 "id": "FT-10",
774 "title": "Time to read",
775 "category": "Speed",
776 "claim": "In ordinary conditions a CKey reads in under 2 seconds from pointing the camera.",
777 "rationale": "Speed decides whether people keep using a code. The decoder's speed on real phones has not been measured yet; this collects the first numbers.",
778 "time_minutes": 10,
779 "setup": [
780 "Print the test sheet at 100% scale; the code is 2.0 inches wide.",
781 "Use ordinary indoor light. Open the reader and leave it on the camera view.",
782 "Use a stopwatch, or a second person to time."
783 ],
784 "steps": [
785 "Point away from the code, then start the stopwatch as you point at it from about 20 cm.",
786 "Stop it when the result appears.",
787 "Repeat 10 times and record each time."
788 ],
789 "codes": [
790 {
791 "label": "A",
792 "payload": "https://openckey.org/t/FT10-A",
793 "level": "M",
794 "layout": "standard",
795 "style": "plain",
796 "size_in": 2.0
797 }
798 ],
799 "measurements": [
800 {
801 "id": "seconds",
802 "label": "Seconds to result",
803 "type": "number",
804 "unit": "s",
805 "min": 0,
806 "max": 60,
807 "trials": [
808 "1",
809 "2",
810 "3",
811 "4",
812 "5",
813 "6",
814 "7",
815 "8",
816 "9",
817 "10"
818 ],
819 "required": true
820 }
821 ],
822 "rubric": {
823 "pass": "The median of the ten times is under 2 seconds.",
824 "partial": "The median is 2 to 5 seconds.",
825 "fail": "The median is over 5 seconds, or some attempts never read."
826 }
827 },
828 {
829 "id": "FT-11",
830 "title": "Payload safety",
831 "category": "Safety",
832 "claim": "A reader shows what a code holds and acts only on a tap, and flags content that is not a plain link.",
833 "rationale": "A code can hold anything, including a disguised link or a script-like string. The payload conventions say a reader must show the content and never act on its own; this checks that a reader does.",
834 "time_minutes": 10,
835 "setup": [
836 "Print the test sheet at 100% scale, or show it on a second screen."
837 ],
838 "steps": [
839 "Scan each code, A to D.",
840 "For each, record whether the reader showed the content before doing anything, and whether anything happened (a page opened, a call started) without your tap.",
841 "Do not tap through on code C."
842 ],
843 "codes": [
844 {
845 "label": "A",
846 "payload": "https://openckey.org/t/FT11-A",
847 "level": "M",
848 "layout": "standard",
849 "style": "plain",
850 "size_in": 1.5
851 },
852 {
853 "label": "B",
854 "payload": "tel:+15550100",
855 "level": "M",
856 "layout": "standard",
857 "style": "plain",
858 "size_in": 1.5
859 },
860 {
861 "label": "C",
862 "payload": "javascript:alert('field test FT-11')",
863 "level": "M",
864 "layout": "standard",
865 "style": "plain",
866 "size_in": 1.5
867 },
868 {
869 "label": "D",
870 "payload": "Field test FT-11, code D. This is plain text: a reader should show it and offer to copy it, not open anything.",
871 "level": "M",
872 "layout": "standard",
873 "style": "plain",
874 "size_in": 1.5
875 }
876 ],
877 "measurements": [
878 {
879 "id": "shown",
880 "label": "Content shown before any action",
881 "type": "boolean",
882 "trials": [
883 "A link",
884 "B phone",
885 "C script",
886 "D text"
887 ],
888 "required": true
889 },
890 {
891 "id": "acted",
892 "label": "Something happened without a tap",
893 "type": "boolean",
894 "trials": [
895 "A link",
896 "B phone",
897 "C script",
898 "D text"
899 ],
900 "required": true
901 }
902 ],
903 "rubric": {
904 "pass": "Every code's content was shown first and nothing happened without a tap; code C offered no way to run it.",
905 "partial": "Every code's content was shown first and nothing happened without a tap, but code C could be run.",
906 "fail": "Anything happened without a tap."
907 }
908 }
909 ]
910}