@portll/cobolwork 0.6.0 → 0.7.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 (140) hide show
  1. package/README.md +49 -18
  2. package/STABILITY.md +76 -0
  3. package/bin/cobolwork.mjs +30 -7
  4. package/lib/bms.mjs +21 -7
  5. package/lib/build.mjs +108 -53
  6. package/lib/capabilities.mjs +9 -10
  7. package/lib/cics-commands.mjs +501 -9
  8. package/lib/compliance.mjs +11 -0
  9. package/lib/consequence.mjs +13 -0
  10. package/lib/control-workers.mjs +161 -0
  11. package/lib/control.mjs +52 -3
  12. package/lib/dataflow.mjs +176 -125
  13. package/lib/db2/cursor.mjs +15 -0
  14. package/lib/db2/read.mjs +170 -0
  15. package/lib/db2/rules.mjs +77 -0
  16. package/lib/db2/stmt/alter.mjs +473 -0
  17. package/lib/db2/stmt/grant.mjs +125 -0
  18. package/lib/db2/stmt/index.mjs +141 -0
  19. package/lib/db2/stmt/misc.mjs +325 -0
  20. package/lib/db2/stmt/routine.mjs +564 -0
  21. package/lib/db2/stmt/storage.mjs +146 -0
  22. package/lib/db2/stmt/table.mjs +540 -0
  23. package/lib/db2/stmt/view.mjs +146 -0
  24. package/lib/diff.mjs +17 -5
  25. package/lib/evidence/cli.mjs +14 -3
  26. package/lib/evidence/record.mjs +1 -1
  27. package/lib/evidence/store.mjs +44 -31
  28. package/lib/exec-reading.mjs +51 -0
  29. package/lib/execution.mjs +3 -2
  30. package/lib/explain.mjs +2 -0
  31. package/lib/exploitability.mjs +11 -2
  32. package/lib/hlasm/asm/data.mjs +13 -1
  33. package/lib/hlasm/asm/sections.mjs +3 -1
  34. package/lib/hlasm/instr.mjs +25 -0
  35. package/lib/hlasm/macro/authorization.mjs +24 -4
  36. package/lib/hlasm/macro/datasets.mjs +30 -17
  37. package/lib/hlasm/macro/io.mjs +68 -45
  38. package/lib/hlasm/macro/le.mjs +2 -2
  39. package/lib/hlasm/macro/operator.mjs +32 -21
  40. package/lib/hlasm/macro/program.mjs +126 -84
  41. package/lib/hlasm/macro/recovery.mjs +10 -5
  42. package/lib/hlasm/macro/storage.mjs +64 -14
  43. package/lib/hlasm/macro/structured.mjs +1 -1
  44. package/lib/hlasm/model.mjs +35 -10
  45. package/lib/hlasm/mvs38.mjs +47 -0
  46. package/lib/hlasm/operands.mjs +10 -0
  47. package/lib/hlasm/optable.mjs +61 -0
  48. package/lib/hlasm/read.mjs +22 -8
  49. package/lib/hlasm.mjs +44 -7
  50. package/lib/ims/dli.mjs +37 -0
  51. package/lib/ims/macro/dbd.mjs +299 -0
  52. package/lib/ims/macro/psb.mjs +286 -0
  53. package/lib/ims/model.mjs +149 -0
  54. package/lib/ims/operands.mjs +23 -0
  55. package/lib/ims/read.mjs +37 -0
  56. package/lib/ims/rules.mjs +135 -0
  57. package/lib/ironwork.mjs +17 -13
  58. package/lib/kernel/pds-archive.mjs +256 -0
  59. package/lib/kernel/registry.mjs +14 -8
  60. package/lib/kernel/shared-pass.mjs +34 -9
  61. package/lib/kernel/source-tree.mjs +104 -36
  62. package/lib/kernel/version-key.mjs +17 -0
  63. package/lib/layout.mjs +26 -31
  64. package/lib/parser.mjs +136 -17
  65. package/lib/pli/cursor.mjs +15 -0
  66. package/lib/pli/expr.mjs +101 -0
  67. package/lib/pli/include.mjs +82 -0
  68. package/lib/pli/layout.mjs +125 -0
  69. package/lib/pli/lex.mjs +198 -0
  70. package/lib/pli/program.mjs +280 -0
  71. package/lib/pli/rules/based.mjs +95 -0
  72. package/lib/pli/rules/conditions.mjs +68 -0
  73. package/lib/pli/rules/entry.mjs +130 -0
  74. package/lib/pli/rules/index.mjs +24 -0
  75. package/lib/pli/rules/preprocessor.mjs +55 -0
  76. package/lib/pli/statements.mjs +130 -0
  77. package/lib/pli/stmt/alloc.mjs +45 -0
  78. package/lib/pli/stmt/assignment.mjs +56 -0
  79. package/lib/pli/stmt/call.mjs +104 -0
  80. package/lib/pli/stmt/conditions.mjs +94 -0
  81. package/lib/pli/stmt/control.mjs +219 -0
  82. package/lib/pli/stmt/declare.mjs +149 -0
  83. package/lib/pli/stmt/exec.mjs +55 -0
  84. package/lib/pli/stmt/io.mjs +239 -0
  85. package/lib/pli/stmt/misc.mjs +4 -0
  86. package/lib/pli/stmt/preprocessor.mjs +242 -0
  87. package/lib/pli/stmt/procedure.mjs +258 -0
  88. package/lib/pli/stmt/stream.mjs +283 -0
  89. package/lib/pli/storage.mjs +129 -0
  90. package/lib/precompile-check.mjs +124 -0
  91. package/lib/precompile-cics.mjs +7 -3
  92. package/lib/reach.mjs +11 -2
  93. package/lib/revision.json +1 -1
  94. package/lib/sarif.mjs +41 -3
  95. package/lib/scan.mjs +7 -1
  96. package/lib/sets/abend.mjs +16 -6
  97. package/lib/sets/cics.mjs +15 -35
  98. package/lib/sets/compile.mjs +41 -15
  99. package/lib/sets/crypto.mjs +5 -3
  100. package/lib/sets/ddl.mjs +36 -0
  101. package/lib/sets/flow.mjs +18 -1
  102. package/lib/sets/hidden.mjs +5 -3
  103. package/lib/sets/hlasm.mjs +72 -12
  104. package/lib/sets/ims.mjs +139 -0
  105. package/lib/sets/log.mjs +6 -6
  106. package/lib/sets/opaque.mjs +27 -7
  107. package/lib/sets/pli.mjs +40 -0
  108. package/lib/sets/recon.mjs +5 -3
  109. package/lib/sets/secrets.mjs +5 -3
  110. package/lib/sets/semantics.mjs +3 -0
  111. package/lib/sets/web.mjs +36 -22
  112. package/lib/site.mjs +10 -0
  113. package/lib/sources.mjs +80 -20
  114. package/lib/statement-cursor.mjs +67 -0
  115. package/lib/verify.mjs +3 -2
  116. package/lib/version.mjs +6 -0
  117. package/package.json +3 -2
  118. package/rules/compliance-cobit2019.json +432 -1
  119. package/rules/compliance-dora.json +414 -1
  120. package/rules/compliance-ffiec.json +414 -1
  121. package/rules/compliance-nist80053.json +466 -1
  122. package/rules/hlasm-optables.json +8024 -0
  123. package/schema/cobolwork-baseline.schema.json +36 -0
  124. package/schema/cobolwork-build-provenance.schema.json +187 -0
  125. package/schema/cobolwork-build.schema.json +382 -0
  126. package/schema/cobolwork-capabilities.schema.json +239 -0
  127. package/schema/cobolwork-diff.schema.json +217 -0
  128. package/schema/cobolwork-evidence.schema.json +161 -0
  129. package/schema/cobolwork-execution.schema.json +53 -0
  130. package/schema/cobolwork-explain.schema.json +360 -0
  131. package/schema/cobolwork-finding.schema.json +465 -0
  132. package/schema/cobolwork-flow.schema.json +465 -0
  133. package/schema/cobolwork-gate.schema.json +211 -0
  134. package/schema/cobolwork-inventory.schema.json +206 -0
  135. package/schema/cobolwork-parse.schema.json +105 -0
  136. package/schema/cobolwork-reach.schema.json +74 -0
  137. package/schema/cobolwork-report.schema.json +559 -0
  138. package/schema/cobolwork-witness.schema.json +107 -0
  139. package/schema/cobolwork.baseline.schema.json +101 -0
  140. package/schema/cobolwork.site.schema.json +116 -0
@@ -0,0 +1,559 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/Portll/cobolwork/schema/cobolwork-report.schema.json",
4
+ "title": "cobolwork scan report",
5
+ "description": "The report cobolwork scan writes as JSON, tool cobolwork. README.md describes it. A later minor release may add keys; a reader ignores keys it does not know.",
6
+ "type": "object",
7
+ "required": [
8
+ "tool",
9
+ "schemaVersion",
10
+ "summary",
11
+ "findings",
12
+ "ruleText",
13
+ "ruleCwe",
14
+ "ruleEvidence",
15
+ "evidence"
16
+ ],
17
+ "properties": {
18
+ "tool": {
19
+ "const": "cobolwork"
20
+ },
21
+ "schemaVersion": {
22
+ "const": 3
23
+ },
24
+ "summary": {
25
+ "type": "object",
26
+ "required": [
27
+ "findings",
28
+ "byRule",
29
+ "filesScanned",
30
+ "coverageIncomplete",
31
+ "identity",
32
+ "flowModel",
33
+ "toolVersion"
34
+ ],
35
+ "properties": {
36
+ "findings": {
37
+ "type": "integer",
38
+ "minimum": 0,
39
+ "description": "Findings in the report, after any baseline."
40
+ },
41
+ "byRule": {
42
+ "type": "object",
43
+ "additionalProperties": {
44
+ "type": "integer",
45
+ "minimum": 0
46
+ }
47
+ },
48
+ "bySeverity": {
49
+ "type": "object",
50
+ "additionalProperties": {
51
+ "type": "integer",
52
+ "minimum": 0
53
+ }
54
+ },
55
+ "byEvidence": {
56
+ "type": "object",
57
+ "additionalProperties": {
58
+ "type": "integer",
59
+ "minimum": 0
60
+ }
61
+ },
62
+ "filesScanned": {
63
+ "type": "integer",
64
+ "minimum": 0,
65
+ "description": "Files the widest rule set read."
66
+ },
67
+ "bySet": {
68
+ "type": "object",
69
+ "description": "Each rule set's own summary: what it read, what it could not, and why it stopped.",
70
+ "additionalProperties": {
71
+ "type": "object"
72
+ }
73
+ },
74
+ "programs": {
75
+ "type": "integer",
76
+ "minimum": 0
77
+ },
78
+ "programFiles": {
79
+ "type": "integer",
80
+ "minimum": 0
81
+ },
82
+ "copybookFiles": {
83
+ "type": "integer",
84
+ "minimum": 0
85
+ },
86
+ "jclFiles": {
87
+ "type": "integer",
88
+ "minimum": 0
89
+ },
90
+ "copiesMissing": {
91
+ "type": "integer",
92
+ "minimum": 0
93
+ },
94
+ "filesUnreadable": {
95
+ "type": "integer",
96
+ "minimum": 0
97
+ },
98
+ "filesEbcdic": {
99
+ "type": "integer",
100
+ "minimum": 0
101
+ },
102
+ "filesOverBudget": {
103
+ "type": "integer",
104
+ "minimum": 0
105
+ },
106
+ "cicsPrograms": {
107
+ "type": [
108
+ "integer",
109
+ "null"
110
+ ]
111
+ },
112
+ "crossProgram": {
113
+ "type": "integer",
114
+ "minimum": 0
115
+ },
116
+ "repos": {
117
+ "type": "integer",
118
+ "minimum": 0,
119
+ "description": "With --repos: how many repositories the report covers."
120
+ },
121
+ "perRepo": {
122
+ "type": "object",
123
+ "description": "With --repos: each repository's own counts.",
124
+ "additionalProperties": {
125
+ "type": "object"
126
+ }
127
+ },
128
+ "advisoryFeeds": {
129
+ "type": "array",
130
+ "description": "The advisory extracts the scan was given."
131
+ },
132
+ "advisoryCoverage": {
133
+ "type": "object",
134
+ "description": "The products the advisory rules searched."
135
+ },
136
+ "byTransaction": {
137
+ "type": "object",
138
+ "additionalProperties": {
139
+ "type": "integer",
140
+ "minimum": 0
141
+ }
142
+ },
143
+ "byJob": {
144
+ "type": "object",
145
+ "additionalProperties": {
146
+ "type": "integer",
147
+ "minimum": 0
148
+ }
149
+ },
150
+ "siteWarnings": {
151
+ "type": "array",
152
+ "items": {
153
+ "type": "string"
154
+ },
155
+ "description": "Keys in cobolwork.site.json this cobolwork does not read."
156
+ },
157
+ "feedWarnings": {
158
+ "type": "array",
159
+ "items": {
160
+ "type": "string"
161
+ },
162
+ "description": "Keys in a witness feed or reachability extract this cobolwork does not read."
163
+ },
164
+ "byReach": {
165
+ "type": "object",
166
+ "additionalProperties": {
167
+ "type": "integer",
168
+ "minimum": 0
169
+ }
170
+ },
171
+ "byEffect": {
172
+ "type": "object",
173
+ "additionalProperties": {
174
+ "type": "integer",
175
+ "minimum": 0
176
+ }
177
+ },
178
+ "reachFeeds": {
179
+ "type": "array",
180
+ "items": {
181
+ "type": "object",
182
+ "properties": {
183
+ "file": {
184
+ "type": "string"
185
+ },
186
+ "extract": {
187
+ "type": "string"
188
+ },
189
+ "retrieved": {
190
+ "type": "string"
191
+ }
192
+ }
193
+ }
194
+ },
195
+ "reachFeedProblems": {
196
+ "type": "array",
197
+ "items": {
198
+ "type": "string"
199
+ }
200
+ },
201
+ "reachNote": {
202
+ "type": "string"
203
+ },
204
+ "effectNote": {
205
+ "type": "string"
206
+ },
207
+ "byExploitability": {
208
+ "type": "object",
209
+ "additionalProperties": {
210
+ "type": "integer",
211
+ "minimum": 0
212
+ }
213
+ },
214
+ "handling": {
215
+ "type": "string"
216
+ },
217
+ "witnessFeeds": {
218
+ "type": "array",
219
+ "items": {
220
+ "type": "object",
221
+ "properties": {
222
+ "file": {
223
+ "type": "string"
224
+ },
225
+ "witness": {
226
+ "type": "string"
227
+ },
228
+ "recorded": {
229
+ "type": "string"
230
+ }
231
+ }
232
+ }
233
+ },
234
+ "byWitness": {
235
+ "type": "object",
236
+ "additionalProperties": {
237
+ "type": "integer",
238
+ "minimum": 0
239
+ }
240
+ },
241
+ "witnessFeedProblems": {
242
+ "type": "array",
243
+ "items": {
244
+ "type": "string"
245
+ }
246
+ },
247
+ "witnessUnmatched": {
248
+ "type": "array",
249
+ "items": {
250
+ "type": "string"
251
+ },
252
+ "description": "Fingerprints a witness result names and no finding carries."
253
+ },
254
+ "witnessOverruled": {
255
+ "type": "array",
256
+ "items": {
257
+ "type": "object"
258
+ }
259
+ },
260
+ "executionFeeds": {
261
+ "type": "array",
262
+ "items": {
263
+ "type": "object",
264
+ "properties": {
265
+ "file": {
266
+ "type": "string"
267
+ },
268
+ "programs": {
269
+ "type": "integer",
270
+ "minimum": 0
271
+ }
272
+ }
273
+ }
274
+ },
275
+ "byExecution": {
276
+ "type": "object",
277
+ "additionalProperties": {
278
+ "type": "integer",
279
+ "minimum": 0
280
+ }
281
+ },
282
+ "executionFeedProblems": {
283
+ "type": "array",
284
+ "items": {
285
+ "type": "string"
286
+ }
287
+ },
288
+ "ruleSets": {
289
+ "type": "array",
290
+ "items": {
291
+ "type": "string"
292
+ }
293
+ },
294
+ "flowModel": {
295
+ "type": "string"
296
+ },
297
+ "toolVersion": {
298
+ "type": "string"
299
+ },
300
+ "identity": {
301
+ "type": "object",
302
+ "required": [
303
+ "version",
304
+ "shared"
305
+ ],
306
+ "properties": {
307
+ "version": {
308
+ "const": "cobolwork/v1"
309
+ },
310
+ "shared": {
311
+ "type": "integer",
312
+ "minimum": 0
313
+ }
314
+ }
315
+ },
316
+ "nosrc": {
317
+ "type": "boolean",
318
+ "description": "No source file was read."
319
+ },
320
+ "coverageIncomplete": {
321
+ "type": "boolean",
322
+ "description": "Some source was not read. Read this before the finding count."
323
+ },
324
+ "setsIncomplete": {
325
+ "type": "array",
326
+ "items": {
327
+ "type": "object",
328
+ "required": [
329
+ "set",
330
+ "kind",
331
+ "why"
332
+ ],
333
+ "properties": {
334
+ "set": {
335
+ "type": "string"
336
+ },
337
+ "kind": {
338
+ "enum": [
339
+ "configuration",
340
+ "coverage"
341
+ ]
342
+ },
343
+ "why": {
344
+ "type": "string"
345
+ }
346
+ }
347
+ }
348
+ },
349
+ "baseline": {
350
+ "type": "object",
351
+ "description": "What the baseline suppressed, what lapsed, and what no finding matched.",
352
+ "properties": {
353
+ "path": {
354
+ "type": "string"
355
+ },
356
+ "source": {
357
+ "enum": [
358
+ "tree",
359
+ "explicit"
360
+ ]
361
+ },
362
+ "suppressed": {
363
+ "type": "integer",
364
+ "minimum": 0
365
+ },
366
+ "expired": {
367
+ "type": "integer",
368
+ "minimum": 0
369
+ },
370
+ "stale": {
371
+ "type": "integer",
372
+ "minimum": 0
373
+ },
374
+ "refused": {
375
+ "type": "integer",
376
+ "minimum": 0
377
+ },
378
+ "refusedWhy": {
379
+ "type": "string"
380
+ },
381
+ "problems": {
382
+ "type": "array",
383
+ "items": {
384
+ "type": "string"
385
+ }
386
+ }
387
+ }
388
+ },
389
+ "toolRevision": {
390
+ "type": [
391
+ "object",
392
+ "null"
393
+ ],
394
+ "description": "A commit and whether its tree held changes, with where it was read.",
395
+ "properties": {
396
+ "commit": {
397
+ "type": [
398
+ "string",
399
+ "null"
400
+ ]
401
+ },
402
+ "dirty": {
403
+ "type": [
404
+ "boolean",
405
+ "null"
406
+ ]
407
+ },
408
+ "tag": {
409
+ "type": "string"
410
+ },
411
+ "from": {
412
+ "type": "string"
413
+ }
414
+ }
415
+ },
416
+ "revision": {
417
+ "type": [
418
+ "object",
419
+ "null"
420
+ ],
421
+ "description": "A commit and whether its tree held changes, with where it was read.",
422
+ "properties": {
423
+ "commit": {
424
+ "type": [
425
+ "string",
426
+ "null"
427
+ ]
428
+ },
429
+ "dirty": {
430
+ "type": [
431
+ "boolean",
432
+ "null"
433
+ ]
434
+ },
435
+ "tag": {
436
+ "type": "string"
437
+ },
438
+ "from": {
439
+ "type": "string"
440
+ }
441
+ }
442
+ },
443
+ "pdsExport": {
444
+ "type": "object",
445
+ "description": "With --pds-export: the export the scan read."
446
+ }
447
+ }
448
+ },
449
+ "inventory": {
450
+ "type": "object",
451
+ "description": "What the reading found in the tree: source formats, missing and refused copybooks, unreadable and EBCDIC files, links and unreadable directories."
452
+ },
453
+ "findings": {
454
+ "type": "array",
455
+ "items": {
456
+ "$ref": "cobolwork-finding.schema.json"
457
+ }
458
+ },
459
+ "checked": {
460
+ "type": "array",
461
+ "description": "Routes a check stops, which are not findings.",
462
+ "items": {
463
+ "$ref": "cobolwork-finding.schema.json"
464
+ }
465
+ },
466
+ "suppressed": {
467
+ "type": "array",
468
+ "description": "Findings a baseline entry suppresses, each with suppressed.",
469
+ "items": {
470
+ "$ref": "cobolwork-finding.schema.json"
471
+ }
472
+ },
473
+ "baselineExpired": {
474
+ "type": "array",
475
+ "description": "Findings back in the report because the judgement lapsed.",
476
+ "items": {
477
+ "type": "object"
478
+ }
479
+ },
480
+ "ruleText": {
481
+ "type": "object",
482
+ "additionalProperties": {
483
+ "type": "string"
484
+ }
485
+ },
486
+ "ruleCwe": {
487
+ "type": "object",
488
+ "additionalProperties": {
489
+ "type": "string"
490
+ }
491
+ },
492
+ "ruleEvidence": {
493
+ "type": "object",
494
+ "additionalProperties": {
495
+ "type": "string"
496
+ }
497
+ },
498
+ "ruleImpact": {
499
+ "type": "object",
500
+ "additionalProperties": {
501
+ "type": "string"
502
+ }
503
+ },
504
+ "ruleRemedy": {
505
+ "type": "object",
506
+ "additionalProperties": {
507
+ "type": "string"
508
+ }
509
+ },
510
+ "evidence": {
511
+ "type": "object",
512
+ "description": "What each evidence kind establishes.",
513
+ "additionalProperties": {
514
+ "type": "string"
515
+ }
516
+ },
517
+ "exploitabilityVerdicts": {
518
+ "type": "object",
519
+ "description": "What each exploitability verdict means.",
520
+ "additionalProperties": {
521
+ "type": "string"
522
+ }
523
+ },
524
+ "ruleCompliance": {
525
+ "type": "object",
526
+ "description": "The clauses each rule bears on.",
527
+ "additionalProperties": {
528
+ "type": "array",
529
+ "items": {
530
+ "type": "object",
531
+ "properties": {
532
+ "framework": {
533
+ "type": "string"
534
+ },
535
+ "clause": {
536
+ "type": "string"
537
+ },
538
+ "title": {
539
+ "type": "string"
540
+ }
541
+ }
542
+ }
543
+ }
544
+ },
545
+ "compliance": {
546
+ "type": "array",
547
+ "description": "Each compliance framework loaded, with what its mapping does not claim.",
548
+ "items": {
549
+ "type": "object"
550
+ }
551
+ },
552
+ "complianceUnloaded": {
553
+ "type": "array",
554
+ "items": {
555
+ "type": "object"
556
+ }
557
+ }
558
+ }
559
+ }
@@ -0,0 +1,107 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/Portll/cobolwork/schema/cobolwork-witness.schema.json",
4
+ "title": "cobolwork witness feed",
5
+ "description": "An estate's own test results, brought as COBOLWORK_WITNESS. docs/spec/reach.md section 9.5. lib/exploitability.mjs reads it; a key it does not read is reported under summary.feedWarnings, and a key opening with an underscore is a note for people.",
6
+ "type": "object",
7
+ "required": [
8
+ "witness",
9
+ "recorded",
10
+ "results"
11
+ ],
12
+ "additionalProperties": false,
13
+ "patternProperties": {
14
+ "^_": {}
15
+ },
16
+ "properties": {
17
+ "$schema": {
18
+ "type": "string"
19
+ },
20
+ "version": {
21
+ "description": "The witness feed version. A feed without one is read as version 0, which holds the same keys as version 1.",
22
+ "type": "integer",
23
+ "minimum": 0,
24
+ "maximum": 1
25
+ },
26
+ "witness": {
27
+ "type": "string",
28
+ "minLength": 1,
29
+ "description": "Whose tests the results are."
30
+ },
31
+ "recorded": {
32
+ "$ref": "#/$defs/date",
33
+ "description": "When the feed was recorded."
34
+ },
35
+ "results": {
36
+ "type": "object",
37
+ "description": "One result per finding, keyed by its fingerprint.",
38
+ "additionalProperties": {
39
+ "$ref": "#/$defs/result"
40
+ }
41
+ }
42
+ },
43
+ "$defs": {
44
+ "date": {
45
+ "type": "string",
46
+ "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
47
+ },
48
+ "result": {
49
+ "type": "object",
50
+ "required": [
51
+ "outcome",
52
+ "by",
53
+ "on",
54
+ "system"
55
+ ],
56
+ "additionalProperties": false,
57
+ "patternProperties": {
58
+ "^_": {}
59
+ },
60
+ "properties": {
61
+ "outcome": {
62
+ "enum": [
63
+ "reproduced",
64
+ "not-reproduced"
65
+ ]
66
+ },
67
+ "by": {
68
+ "type": "string",
69
+ "minLength": 1,
70
+ "description": "Who ran the test."
71
+ },
72
+ "on": {
73
+ "$ref": "#/$defs/date",
74
+ "description": "When the test ran."
75
+ },
76
+ "system": {
77
+ "type": "string",
78
+ "minLength": 1,
79
+ "description": "The system the test ran on."
80
+ },
81
+ "reference": {
82
+ "type": "string",
83
+ "description": "A change or ticket the test belongs to."
84
+ },
85
+ "evidence": {
86
+ "type": "object",
87
+ "description": "The ironwork run that reproduced the finding: an evidence directory relative to the feed, and the run's id.",
88
+ "required": [
89
+ "dir",
90
+ "run"
91
+ ],
92
+ "additionalProperties": false,
93
+ "properties": {
94
+ "dir": {
95
+ "type": "string",
96
+ "minLength": 1
97
+ },
98
+ "run": {
99
+ "type": "string",
100
+ "pattern": "^[0-9TZ]+-[0-9a-f]{16}$"
101
+ }
102
+ }
103
+ }
104
+ }
105
+ }
106
+ }
107
+ }