monkeypatchlist 0.0.0-stage → 0.1.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 (221) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +61 -0
  3. package/README.md +183 -2
  4. package/catalog/catalog.json +552211 -0
  5. package/catalog/catalog.schema.json +787 -0
  6. package/catalog/changelog.json +3 -0
  7. package/dist/bin/monkeypatchlist.d.ts +2 -0
  8. package/dist/bin/monkeypatchlist.js +3 -0
  9. package/dist/catalog.d.ts +561 -0
  10. package/dist/catalog.js +58 -0
  11. package/dist/cli.d.ts +84 -0
  12. package/dist/cli.js +470 -0
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.js +1 -0
  15. package/dist/lockfile-input.d.ts +9 -0
  16. package/dist/lockfile-input.js +91 -0
  17. package/dist/packages/analysis/binding.d.ts +2 -0
  18. package/dist/packages/analysis/binding.js +5 -0
  19. package/dist/packages/analysis/index.d.ts +10 -0
  20. package/dist/packages/analysis/index.js +13 -0
  21. package/dist/packages/analysis/job.d.ts +33 -0
  22. package/dist/packages/analysis/job.js +85 -0
  23. package/dist/packages/analysis/lib/absence-tags.d.ts +34 -0
  24. package/dist/packages/analysis/lib/absence-tags.js +340 -0
  25. package/dist/packages/analysis/lib/ast.d.ts +28 -0
  26. package/dist/packages/analysis/lib/ast.js +64 -0
  27. package/dist/packages/analysis/lib/binding.d.ts +36 -0
  28. package/dist/packages/analysis/lib/binding.js +66 -0
  29. package/dist/packages/analysis/lib/budget.d.ts +80 -0
  30. package/dist/packages/analysis/lib/budget.js +31 -0
  31. package/dist/packages/analysis/lib/catch-arms.d.ts +19 -0
  32. package/dist/packages/analysis/lib/catch-arms.js +351 -0
  33. package/dist/packages/analysis/lib/chunk-loads.d.ts +160 -0
  34. package/dist/packages/analysis/lib/chunk-loads.js +882 -0
  35. package/dist/packages/analysis/lib/chunk-registry.d.ts +45 -0
  36. package/dist/packages/analysis/lib/chunk-registry.js +334 -0
  37. package/dist/packages/analysis/lib/code-routes.d.ts +52 -0
  38. package/dist/packages/analysis/lib/code-routes.js +921 -0
  39. package/dist/packages/analysis/lib/collisions.d.ts +22 -0
  40. package/dist/packages/analysis/lib/collisions.js +103 -0
  41. package/dist/packages/analysis/lib/definitions.d.ts +76 -0
  42. package/dist/packages/analysis/lib/definitions.js +782 -0
  43. package/dist/packages/analysis/lib/early-exits.d.ts +39 -0
  44. package/dist/packages/analysis/lib/early-exits.js +161 -0
  45. package/dist/packages/analysis/lib/effect.d.ts +138 -0
  46. package/dist/packages/analysis/lib/effect.js +800 -0
  47. package/dist/packages/analysis/lib/global-object.d.ts +581 -0
  48. package/dist/packages/analysis/lib/global-object.js +8240 -0
  49. package/dist/packages/analysis/lib/keys.d.ts +33 -0
  50. package/dist/packages/analysis/lib/keys.js +82 -0
  51. package/dist/packages/analysis/lib/line-starts.d.ts +41 -0
  52. package/dist/packages/analysis/lib/line-starts.js +79 -0
  53. package/dist/packages/analysis/lib/link-group.d.ts +51 -0
  54. package/dist/packages/analysis/lib/link-group.js +487 -0
  55. package/dist/packages/analysis/lib/module-links.d.ts +117 -0
  56. package/dist/packages/analysis/lib/module-links.js +1060 -0
  57. package/dist/packages/analysis/lib/nested-code.d.ts +38 -0
  58. package/dist/packages/analysis/lib/nested-code.js +200 -0
  59. package/dist/packages/analysis/lib/numeric.d.ts +16 -0
  60. package/dist/packages/analysis/lib/numeric.js +216 -0
  61. package/dist/packages/analysis/lib/once-flags.d.ts +12 -0
  62. package/dist/packages/analysis/lib/once-flags.js +190 -0
  63. package/dist/packages/analysis/lib/parameter-arguments.d.ts +12 -0
  64. package/dist/packages/analysis/lib/parameter-arguments.js +34 -0
  65. package/dist/packages/analysis/lib/parse.d.ts +10 -0
  66. package/dist/packages/analysis/lib/parse.js +39 -0
  67. package/dist/packages/analysis/lib/partial.d.ts +60 -0
  68. package/dist/packages/analysis/lib/partial.js +518 -0
  69. package/dist/packages/analysis/lib/print.d.ts +3 -0
  70. package/dist/packages/analysis/lib/print.js +150 -0
  71. package/dist/packages/analysis/lib/reachability.d.ts +137 -0
  72. package/dist/packages/analysis/lib/reachability.js +1295 -0
  73. package/dist/packages/analysis/lib/resolver.d.ts +13 -0
  74. package/dist/packages/analysis/lib/resolver.js +2886 -0
  75. package/dist/packages/analysis/lib/restores.d.ts +42 -0
  76. package/dist/packages/analysis/lib/restores.js +482 -0
  77. package/dist/packages/analysis/lib/rewritten-deletes.d.ts +6 -0
  78. package/dist/packages/analysis/lib/rewritten-deletes.js +142 -0
  79. package/dist/packages/analysis/lib/scope.d.ts +110 -0
  80. package/dist/packages/analysis/lib/scope.js +443 -0
  81. package/dist/packages/analysis/lib/script-loads.d.ts +56 -0
  82. package/dist/packages/analysis/lib/script-loads.js +359 -0
  83. package/dist/packages/analysis/lib/summaries.d.ts +177 -0
  84. package/dist/packages/analysis/lib/summaries.js +498 -0
  85. package/dist/packages/analysis/lib/types.d.ts +632 -0
  86. package/dist/packages/analysis/lib/types.js +128 -0
  87. package/dist/packages/analysis/lib/wrap.d.ts +34 -0
  88. package/dist/packages/analysis/lib/wrap.js +407 -0
  89. package/dist/packages/analysis/lib/writes.d.ts +358 -0
  90. package/dist/packages/analysis/lib/writes.js +1612 -0
  91. package/dist/packages/analysis/visit-order.d.ts +3 -0
  92. package/dist/packages/analysis/visit-order.js +23 -0
  93. package/dist/packages/attribution/index.d.ts +233 -0
  94. package/dist/packages/attribution/index.js +444 -0
  95. package/dist/packages/attribution/lib/containing-package.d.ts +76 -0
  96. package/dist/packages/attribution/lib/containing-package.js +304 -0
  97. package/dist/packages/attribution/lib/first-party.d.ts +37 -0
  98. package/dist/packages/attribution/lib/first-party.js +153 -0
  99. package/dist/packages/attribution/lib/lockfile-graph.d.ts +99 -0
  100. package/dist/packages/attribution/lib/lockfile-graph.js +158 -0
  101. package/dist/packages/attribution/lib/lockfile.d.ts +33 -0
  102. package/dist/packages/attribution/lib/lockfile.js +330 -0
  103. package/dist/packages/attribution/lib/path-rules.d.ts +29 -0
  104. package/dist/packages/attribution/lib/path-rules.js +84 -0
  105. package/dist/packages/attribution/lib/pnpm.d.ts +4 -0
  106. package/dist/packages/attribution/lib/pnpm.js +133 -0
  107. package/dist/packages/attribution/lib/remote-url.d.ts +7 -0
  108. package/dist/packages/attribution/lib/remote-url.js +24 -0
  109. package/dist/packages/attribution/lib/source-map.d.ts +51 -0
  110. package/dist/packages/attribution/lib/source-map.js +125 -0
  111. package/dist/packages/attribution/lib/yaml.d.ts +9 -0
  112. package/dist/packages/attribution/lib/yaml.js +277 -0
  113. package/dist/packages/attribution/lib/yarn.d.ts +7 -0
  114. package/dist/packages/attribution/lib/yarn.js +227 -0
  115. package/dist/packages/baseline/index.d.ts +45 -0
  116. package/dist/packages/baseline/index.js +41 -0
  117. package/dist/packages/baseline/lib/error.d.ts +15 -0
  118. package/dist/packages/baseline/lib/error.js +25 -0
  119. package/dist/packages/baseline/lib/format.d.ts +49 -0
  120. package/dist/packages/baseline/lib/format.js +22 -0
  121. package/dist/packages/baseline/lib/migrations.d.ts +19 -0
  122. package/dist/packages/baseline/lib/migrations.js +7 -0
  123. package/dist/packages/baseline/lib/previous.d.ts +23 -0
  124. package/dist/packages/baseline/lib/previous.js +64 -0
  125. package/dist/packages/baseline/lib/read.d.ts +39 -0
  126. package/dist/packages/baseline/lib/read.js +219 -0
  127. package/dist/packages/baseline/lib/report.d.ts +25 -0
  128. package/dist/packages/baseline/lib/report.js +104 -0
  129. package/dist/packages/baseline/lib/skew.d.ts +51 -0
  130. package/dist/packages/baseline/lib/skew.js +75 -0
  131. package/dist/packages/compare/index.d.ts +120 -0
  132. package/dist/packages/compare/index.js +274 -0
  133. package/dist/packages/compare/lib/catalog-notes.d.ts +73 -0
  134. package/dist/packages/compare/lib/catalog-notes.js +224 -0
  135. package/dist/packages/completeness/index.d.ts +246 -0
  136. package/dist/packages/completeness/index.js +249 -0
  137. package/dist/packages/confidence/index.d.ts +54 -0
  138. package/dist/packages/confidence/index.js +71 -0
  139. package/dist/packages/config/index.d.ts +107 -0
  140. package/dist/packages/config/index.js +95 -0
  141. package/dist/packages/config/lib/command-line.d.ts +23 -0
  142. package/dist/packages/config/lib/command-line.js +239 -0
  143. package/dist/packages/config/lib/config-file.d.ts +11 -0
  144. package/dist/packages/config/lib/config-file.js +119 -0
  145. package/dist/packages/config/lib/scan-config-id.d.ts +28 -0
  146. package/dist/packages/config/lib/scan-config-id.js +54 -0
  147. package/dist/packages/config/lib/schema.d.ts +2 -0
  148. package/dist/packages/config/lib/schema.js +31 -0
  149. package/dist/packages/config/lib/types.d.ts +64 -0
  150. package/dist/packages/config/lib/types.js +6 -0
  151. package/dist/packages/config/lib/urls.d.ts +6 -0
  152. package/dist/packages/config/lib/urls.js +9 -0
  153. package/dist/packages/discovery/index.d.ts +277 -0
  154. package/dist/packages/discovery/index.js +1950 -0
  155. package/dist/packages/discovery/lib/import-map.d.ts +68 -0
  156. package/dist/packages/discovery/lib/import-map.js +180 -0
  157. package/dist/packages/discovery/lib/requests.d.ts +58 -0
  158. package/dist/packages/discovery/lib/requests.js +591 -0
  159. package/dist/packages/discovery/lib/scopes.d.ts +6 -0
  160. package/dist/packages/discovery/lib/scopes.js +286 -0
  161. package/dist/packages/discovery/lib/source-maps.d.ts +56 -0
  162. package/dist/packages/discovery/lib/source-maps.js +209 -0
  163. package/dist/packages/discovery/lib/swept-code.d.ts +27 -0
  164. package/dist/packages/discovery/lib/swept-code.js +107 -0
  165. package/dist/packages/discovery/lib/syntax.d.ts +17 -0
  166. package/dist/packages/discovery/lib/syntax.js +39 -0
  167. package/dist/packages/findings/index.d.ts +106 -0
  168. package/dist/packages/findings/index.js +254 -0
  169. package/dist/packages/findings/lib/scope.d.ts +38 -0
  170. package/dist/packages/findings/lib/scope.js +110 -0
  171. package/dist/packages/parallel/index.d.ts +2 -0
  172. package/dist/packages/parallel/index.js +5 -0
  173. package/dist/packages/parallel/lib/protocol.d.ts +15 -0
  174. package/dist/packages/parallel/lib/protocol.js +2 -0
  175. package/dist/packages/parallel/lib/runner.d.ts +36 -0
  176. package/dist/packages/parallel/lib/runner.js +96 -0
  177. package/dist/packages/parallel/lib/schedule.d.ts +16 -0
  178. package/dist/packages/parallel/lib/schedule.js +52 -0
  179. package/dist/packages/parallel/lib/worker.d.ts +1 -0
  180. package/dist/packages/parallel/lib/worker.js +18 -0
  181. package/dist/packages/policy/index.d.ts +36 -0
  182. package/dist/packages/policy/index.js +22 -0
  183. package/dist/packages/report/explain.d.ts +26 -0
  184. package/dist/packages/report/explain.js +99 -0
  185. package/dist/packages/report/index.d.ts +210 -0
  186. package/dist/packages/report/index.js +388 -0
  187. package/dist/packages/report/terminal.d.ts +11 -0
  188. package/dist/packages/report/terminal.js +331 -0
  189. package/dist/packages/source-store/fixture.d.ts +22 -0
  190. package/dist/packages/source-store/fixture.js +58 -0
  191. package/dist/packages/source-store/index.d.ts +278 -0
  192. package/dist/packages/source-store/index.js +322 -0
  193. package/dist/packages/source-store/lib/addresses.d.ts +6 -0
  194. package/dist/packages/source-store/lib/addresses.js +91 -0
  195. package/dist/packages/source-store/lib/connection.d.ts +15 -0
  196. package/dist/packages/source-store/lib/connection.js +135 -0
  197. package/dist/packages/source-store/lib/content-types.d.ts +16 -0
  198. package/dist/packages/source-store/lib/content-types.js +75 -0
  199. package/dist/packages/source-store/lib/data-urls.d.ts +10 -0
  200. package/dist/packages/source-store/lib/data-urls.js +85 -0
  201. package/dist/packages/source-store/lib/deadline.d.ts +18 -0
  202. package/dist/packages/source-store/lib/deadline.js +44 -0
  203. package/dist/packages/source-store/lib/exchange.d.ts +29 -0
  204. package/dist/packages/source-store/lib/exchange.js +112 -0
  205. package/dist/packages/source-store/lib/integrity.d.ts +19 -0
  206. package/dist/packages/source-store/lib/integrity.js +86 -0
  207. package/dist/packages/source-store/lib/outcomes.d.ts +12 -0
  208. package/dist/packages/source-store/lib/outcomes.js +22 -0
  209. package/dist/packages/source-store/lib/proxy.d.ts +11 -0
  210. package/dist/packages/source-store/lib/proxy.js +53 -0
  211. package/dist/packages/source-store/lib/session.d.ts +12 -0
  212. package/dist/packages/source-store/lib/session.js +139 -0
  213. package/dist/packages/source-store/lib/urls.d.ts +6 -0
  214. package/dist/packages/source-store/lib/urls.js +15 -0
  215. package/dist/packages/source-store/resolve.d.ts +59 -0
  216. package/dist/packages/source-store/resolve.js +45 -0
  217. package/dist/scan.d.ts +65 -0
  218. package/dist/scan.js +592 -0
  219. package/package.json +95 -4
  220. package/schema/config.schema.json +133 -0
  221. package/schema/report.schema.json +1905 -0
@@ -0,0 +1,1905 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "monkeypatchlist scan report",
4
+ "description": "The JSON report of `monkeypatchlist scan --json` (spec §15). Adding a field doesn't bump reportVersion; removing, renaming or changing the meaning of one does.",
5
+ "type": "object",
6
+ "required": ["reportVersion", "tool", "application", "config", "summary", "gate", "completeness", "baseline", "packages", "findings", "ineffectiveWrites", "artifacts", "run"],
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "reportVersion": { "const": 1 },
10
+ "tool": {
11
+ "type": "object",
12
+ "required": ["monkeypatchlistVersion", "catalogVersion", "analyzerVersion", "fingerprintScheme"],
13
+ "additionalProperties": false,
14
+ "properties": {
15
+ "monkeypatchlistVersion": { "type": "string" },
16
+ "catalogVersion": { "type": "integer", "minimum": 1 },
17
+ "analyzerVersion": { "type": "string" },
18
+ "fingerprintScheme": { "type": "integer", "minimum": 1 }
19
+ }
20
+ },
21
+ "application": {
22
+ "description": "The scanned application (§16 Application name). It is not identity.",
23
+ "type": "object",
24
+ "required": ["name"],
25
+ "additionalProperties": false,
26
+ "properties": {
27
+ "name": {
28
+ "description": "The config file's `name`, or else the build directory's basename.",
29
+ "type": "string",
30
+ "minLength": 1
31
+ }
32
+ }
33
+ },
34
+ "config": {
35
+ "type": "object",
36
+ "required": ["scanConfigId", "surface", "mode", "entries", "mappings", "sourceMaps", "failOn"],
37
+ "additionalProperties": false,
38
+ "properties": {
39
+ "scanConfigId": {
40
+ "description": "The scan-config id (§16): one part per field that decides which findings can exist (entries, mappings, surface, realms). A baseline is compared only with a scan of the same id.",
41
+ "type": "string"
42
+ },
43
+ "surface": { "description": "The surface reported, baselined and gated (§12).", "enum": ["protected", "all"] },
44
+ "mode": { "enum": ["offline", "resolve"] },
45
+ "entries": {
46
+ "type": "array",
47
+ "items": {
48
+ "type": "object",
49
+ "required": ["file", "url"],
50
+ "additionalProperties": false,
51
+ "properties": { "file": { "type": "string" }, "url": { "type": "string" } }
52
+ }
53
+ },
54
+ "mappings": {
55
+ "type": "array",
56
+ "items": {
57
+ "type": "object",
58
+ "required": ["url", "dir"],
59
+ "additionalProperties": false,
60
+ "properties": { "url": { "type": "string" }, "dir": { "type": "string" } }
61
+ }
62
+ },
63
+ "sourceMaps": {
64
+ "description": "The source-map directories (§2 Source maps), as declared, in the order they were searched.",
65
+ "type": "array",
66
+ "items": { "type": "string" }
67
+ },
68
+ "lockfile": {
69
+ "description": "The lockfile as given (--lockfile, config lockfile.path) and the lockfile.importer setting, or null when none was given (§10 Introducing dependencies). It isn't in the scan-config id.",
70
+ "oneOf": [
71
+ { "type": "null" },
72
+ {
73
+ "type": "object",
74
+ "required": ["path", "importer"],
75
+ "additionalProperties": false,
76
+ "properties": { "path": { "type": "string" }, "importer": { "type": ["string", "null"] } }
77
+ }
78
+ ]
79
+ },
80
+ "failOn": { "$ref": "#/$defs/failOn" }
81
+ }
82
+ },
83
+ "summary": {
84
+ "description": "How many findings are in each baseline state (§11), all 0 without a baseline, how many findings a protected scan left out, per surface (§12), and how many ineffective-write records the scan has (§3 Record).",
85
+ "type": "object",
86
+ "required": ["added", "changed", "existing", "removed", "unconfirmed", "outOfScopeBySurface", "ineffectiveWrites"],
87
+ "additionalProperties": false,
88
+ "properties": {
89
+ "added": { "$ref": "#/$defs/count" },
90
+ "changed": { "$ref": "#/$defs/count" },
91
+ "existing": { "$ref": "#/$defs/count" },
92
+ "removed": { "$ref": "#/$defs/count" },
93
+ "unconfirmed": { "$ref": "#/$defs/count" },
94
+ "outOfScopeBySurface": {
95
+ "description": "The findings outside the protected surface that a protected scan leaves out of the finding list and the baseline, per surface (§12). Every surface is listed; all are 0 under --surface all.",
96
+ "type": "object",
97
+ "required": ["networking", "events", "scheduling", "navigation", "storage", "crypto", "DOM", "ECMAScript", "diagnostics", "workers", "other"],
98
+ "additionalProperties": false,
99
+ "properties": {
100
+ "networking": { "$ref": "#/$defs/count" },
101
+ "events": { "$ref": "#/$defs/count" },
102
+ "scheduling": { "$ref": "#/$defs/count" },
103
+ "navigation": { "$ref": "#/$defs/count" },
104
+ "storage": { "$ref": "#/$defs/count" },
105
+ "crypto": { "$ref": "#/$defs/count" },
106
+ "DOM": { "$ref": "#/$defs/count" },
107
+ "ECMAScript": { "$ref": "#/$defs/count" },
108
+ "diagnostics": { "$ref": "#/$defs/count" },
109
+ "workers": { "$ref": "#/$defs/count" },
110
+ "other": { "$ref": "#/$defs/count" }
111
+ }
112
+ },
113
+ "ineffectiveWrites": { "$ref": "#/$defs/count" }
114
+ }
115
+ },
116
+ "gate": {
117
+ "description": "The gate (§11 The gate, §16 Exit codes): the baseline states it fails on, its result, and the exit code it gives. It does not run without --fail-on. The result is the findings' alone; an incomplete scan makes the exit code 3 whether the gate passed or failed, unless --allow-incomplete downgrades that to a warning.",
118
+ "type": "object",
119
+ "required": ["failOn", "result", "exitCode"],
120
+ "additionalProperties": false,
121
+ "properties": {
122
+ "failOn": { "$ref": "#/$defs/failOn" },
123
+ "result": { "enum": ["pass", "fail", "not-run"] },
124
+ "exitCode": { "enum": [0, 1, 3] }
125
+ }
126
+ },
127
+ "completeness": {
128
+ "description": "What the scan did not analyze (§13): its level, counters and limitation records, the build files the sweep excluded, and the attribution block.",
129
+ "type": "object",
130
+ "required": ["level", "counters", "limitations", "excluded", "attribution"],
131
+ "additionalProperties": false,
132
+ "properties": {
133
+ "level": { "enum": ["complete", "complete-with-limitations", "incomplete"] },
134
+ "counters": {
135
+ "type": "object",
136
+ "required": ["artifacts", "blindSpots", "html", "statistics"],
137
+ "additionalProperties": false,
138
+ "properties": {
139
+ "artifacts": {
140
+ "description": "`known` is the denominator: every artifact is analyzed, failed or skipped.",
141
+ "type": "object",
142
+ "required": ["known", "analyzed", "failed", "skipped", "sweepOnly", "otherFiles"],
143
+ "additionalProperties": false,
144
+ "properties": {
145
+ "known": { "$ref": "#/$defs/count" },
146
+ "analyzed": { "$ref": "#/$defs/count" },
147
+ "failed": {
148
+ "description": "Artifacts whose code was never analyzed, by the limitation kind that names them, or `crash-guard` when the wall-clock crash guard fired before the link group that would have analyzed them ran.",
149
+ "type": "object",
150
+ "required": ["parse-failure", "unreadable", "fetch-failed", "sri-mismatch", "crash-guard"],
151
+ "additionalProperties": false,
152
+ "properties": {
153
+ "parse-failure": { "$ref": "#/$defs/count" },
154
+ "unreadable": { "$ref": "#/$defs/count" },
155
+ "fetch-failed": { "$ref": "#/$defs/count" },
156
+ "sri-mismatch": { "$ref": "#/$defs/count" },
157
+ "crash-guard": { "$ref": "#/$defs/count" }
158
+ }
159
+ },
160
+ "skipped": {
161
+ "description": "Artifacts whose code was never analyzed, and that don't make the scan incomplete: skipped in offline mode (`offline`), refused by the safety floor in resolve mode (`refused`, §17), excluded outside a mapping (`excluded`) or not JavaScript (`nonJs`).",
162
+ "type": "object",
163
+ "required": ["offline", "refused", "excluded", "nonJs"],
164
+ "additionalProperties": false,
165
+ "properties": {
166
+ "offline": { "$ref": "#/$defs/count" },
167
+ "refused": { "$ref": "#/$defs/count" },
168
+ "excluded": { "$ref": "#/$defs/count" },
169
+ "nonJs": { "$ref": "#/$defs/count" }
170
+ }
171
+ },
172
+ "sweepOnly": {
173
+ "description": "The artifacts only the build-directory sweep found (§2 Sweep), which the counts above already include.",
174
+ "$ref": "#/$defs/count"
175
+ },
176
+ "otherFiles": {
177
+ "description": "The files a URL mapping serves that no reference found, and that the sweep takes for neither JavaScript (`.js`, `.mjs`, `.cjs`) nor WebAssembly (`.wasm`) (§2 Sweep): entry documents, stylesheets, images, source maps, and code under another extension. Informational: they are not artifacts, so not in `known`, and never change the level.",
178
+ "$ref": "#/$defs/count"
179
+ }
180
+ }
181
+ },
182
+ "blindSpots": {
183
+ "type": "object",
184
+ "required": ["dynamicCode", "unresolvedReference", "realmUncertain", "unresolvedHolder"],
185
+ "additionalProperties": false,
186
+ "properties": {
187
+ "dynamicCode": { "$ref": "#/$defs/count" },
188
+ "unresolvedReference": { "$ref": "#/$defs/count" },
189
+ "realmUncertain": { "$ref": "#/$defs/count" },
190
+ "unresolvedHolder": { "$ref": "#/$defs/count" }
191
+ }
192
+ },
193
+ "html": {
194
+ "description": "HTML content that is not analyzed (§19 HTML rules). Informational: it never changes the level.",
195
+ "type": "object",
196
+ "required": ["nomodule", "inlineHandlers"],
197
+ "additionalProperties": false,
198
+ "properties": {
199
+ "nomodule": { "description": "Classic `<script nomodule>` elements, and injected scripts whose `noModule` is, or may be, set.", "$ref": "#/$defs/count" },
200
+ "inlineHandlers": {
201
+ "description": "Inline event-handler attributes and `javascript:` URLs.",
202
+ "$ref": "#/$defs/count"
203
+ }
204
+ }
205
+ },
206
+ "statistics": {
207
+ "description": "Scan statistics (§13, §18): the steps of every link group analyzed, their step budgets and how many ran out, each cap's hits summed over them, and the budget and caps the scan ran with. Budgets and caps are deterministic, so these are too.",
208
+ "type": "object",
209
+ "required": ["steps", "stepBudget", "budgetExhausted", "caps", "pruned", "limits", "crashGuard"],
210
+ "additionalProperties": false,
211
+ "properties": {
212
+ "steps": { "$ref": "#/$defs/count" },
213
+ "stepBudget": {
214
+ "description": "The step budgets of the link groups analyzed, summed: each group's is its members' source bytes times `limits.stepsPerByte`, rounded down (§18).",
215
+ "$ref": "#/$defs/count"
216
+ },
217
+ "budgetExhausted": {
218
+ "description": "How many link groups exhausted their step budget. Each raised `analysis-budget`; any makes a missing baseline entry `unconfirmed` (§11, §13).",
219
+ "$ref": "#/$defs/count"
220
+ },
221
+ "caps": {
222
+ "description": "Each cap's hits, summed over the link groups.",
223
+ "type": "object",
224
+ "additionalProperties": { "$ref": "#/$defs/count" }
225
+ },
226
+ "pruned": {
227
+ "description": "How many finding occurrences statically false catalog checks pruned (§7 Checking guards against the catalog), plus how many writes `catch` arms whose `try` can't throw dropped (§5 Resolver capabilities 9), summed over the link groups. Each surviving occurrence a pruning check is on, or in such a `try` block, carries a `prune` trace step.",
228
+ "$ref": "#/$defs/count"
229
+ },
230
+ "limits": {
231
+ "description": "The step budget per source byte and the caps the scan ran with (§18). They are implementation detail, never a user flag.",
232
+ "type": "object",
233
+ "required": ["stepsPerByte", "caps"],
234
+ "additionalProperties": false,
235
+ "properties": {
236
+ "stepsPerByte": { "type": "number", "minimum": 0 },
237
+ "caps": { "type": "object", "additionalProperties": { "$ref": "#/$defs/count" } }
238
+ }
239
+ },
240
+ "crashGuard": {
241
+ "description": "Whether the wall-clock crash guard fired (§13, §18). When it fires, no further link group runs and the scan is `incomplete`, with no limitation record; the groups that ran are reported as they would be without it. Only a guard that fires lets wall-clock time reach the report outside `run`.",
242
+ "enum": ["not-fired", "fired"]
243
+ }
244
+ }
245
+ }
246
+ }
247
+ },
248
+ "limitations": {
249
+ "description": "Sorted by artifact, location, kind and detail.",
250
+ "type": "array",
251
+ "items": { "$ref": "#/$defs/limitation" }
252
+ },
253
+ "excluded": {
254
+ "description": "The JavaScript and WebAssembly files of the build directory that no URL mapping serves, which the sweep excluded (§2 Sweep): build-relative POSIX paths, sorted.",
255
+ "type": "array",
256
+ "items": { "type": "string" }
257
+ },
258
+ "attribution": {
259
+ "description": "The attribution block (§13): missing source maps are not a coverage limitation, so they are counted here.",
260
+ "type": "object",
261
+ "required": ["artifacts", "pairings", "staleCandidates", "unreadMaps", "sourceMapDirectories", "cappedFindings"],
262
+ "additionalProperties": false,
263
+ "properties": {
264
+ "artifacts": {
265
+ "description": "Every artifact is counted once: with a verified source map, without one, or with only broken (`stale`) ones.",
266
+ "type": "object",
267
+ "required": ["withMap", "withoutMap", "withBrokenMap"],
268
+ "additionalProperties": false,
269
+ "properties": {
270
+ "withMap": { "$ref": "#/$defs/count" },
271
+ "withoutMap": { "$ref": "#/$defs/count" },
272
+ "withBrokenMap": { "$ref": "#/$defs/count" }
273
+ }
274
+ },
275
+ "pairings": {
276
+ "description": "The artifacts with a source map, by the method that paired it (§2 Source maps).",
277
+ "type": "object",
278
+ "required": ["header", "annotation", "sidecar", "debug-id", "external-debug-id", "external-annotation", "external-sidecar"],
279
+ "additionalProperties": false,
280
+ "properties": {
281
+ "header": { "$ref": "#/$defs/count" },
282
+ "annotation": { "$ref": "#/$defs/count" },
283
+ "sidecar": { "$ref": "#/$defs/count" },
284
+ "debug-id": { "$ref": "#/$defs/count" },
285
+ "external-debug-id": { "$ref": "#/$defs/count" },
286
+ "external-annotation": { "$ref": "#/$defs/count" },
287
+ "external-sidecar": { "$ref": "#/$defs/count" }
288
+ }
289
+ },
290
+ "staleCandidates": {
291
+ "description": "Every candidate source map that failed verification (§2 Source maps), counted once for each artifact it was tried for: those a later method's verified map replaced, and those of an artifact with only broken maps.",
292
+ "$ref": "#/$defs/count"
293
+ },
294
+ "unreadMaps": {
295
+ "description": "The source maps a remote artifact's `SourceMap` header or `sourceMappingURL` annotation names that weren't read, counted once for each artifact that names them, by why: the safety floor refused the fetch, it failed, or the map is a build file that exists but can't be read. They change these counters only, never completeness (§17).",
296
+ "type": "object",
297
+ "required": ["refused", "failed", "unreadable"],
298
+ "additionalProperties": false,
299
+ "properties": {
300
+ "refused": { "$ref": "#/$defs/count" },
301
+ "failed": { "$ref": "#/$defs/count" },
302
+ "unreadable": { "$ref": "#/$defs/count" }
303
+ }
304
+ },
305
+ "sourceMapDirectories": {
306
+ "description": "What became of each source-map directory's maps (§2 Source maps), in the order the directories were declared. A directory's maps are its `.map` files, in any case, and any other file a mirrored annotation named.",
307
+ "type": "array",
308
+ "items": {
309
+ "type": "object",
310
+ "required": ["path", "found", "paired", "stale", "orphaned", "orphanedMaps"],
311
+ "additionalProperties": false,
312
+ "properties": {
313
+ "path": { "description": "The directory, as declared.", "type": "string" },
314
+ "found": { "description": "Its maps.", "$ref": "#/$defs/count" },
315
+ "paired": {
316
+ "description": "Its maps that verified against an artifact through an external method, even one an earlier map had already paired.",
317
+ "$ref": "#/$defs/count"
318
+ },
319
+ "stale": {
320
+ "description": "Its orphaned maps that failed verification against an artifact a method paired them with.",
321
+ "$ref": "#/$defs/count"
322
+ },
323
+ "orphaned": { "description": "Its maps that verified against no artifact.", "$ref": "#/$defs/count" },
324
+ "orphanedMaps": {
325
+ "description": "The orphaned maps' paths, relative to the directory, sorted.",
326
+ "type": "array",
327
+ "items": { "type": "string" }
328
+ }
329
+ }
330
+ }
331
+ },
332
+ "cappedFindings": {
333
+ "description": "The findings whose attribution confidence is capped below high (§9, §13), by the level it is capped at.",
334
+ "type": "object",
335
+ "required": ["medium", "low"],
336
+ "additionalProperties": false,
337
+ "properties": {
338
+ "medium": { "$ref": "#/$defs/count" },
339
+ "low": { "$ref": "#/$defs/count" }
340
+ }
341
+ },
342
+ "introducers": {
343
+ "description": "Why introducers are unknown (§10 Unknown is not empty, §13): `reason` is null with a usable lockfile; otherwise `no-lockfile` (none given, or none usable, with its format version as evidence), `importer-unresolved` or `lockfile-stale`. `evidence` says what made it so. `confidence`, present with a usable lockfile, is how certain its introducers are: `medium` from yarn.lock, whose derived facts are capped there, and `high` otherwise (§10 Formats).",
344
+ "type": "object",
345
+ "required": ["reason", "evidence"],
346
+ "additionalProperties": false,
347
+ "properties": {
348
+ "reason": { "enum": [null, "no-lockfile", "importer-unresolved", "lockfile-stale"] },
349
+ "evidence": { "type": ["string", "null"] },
350
+ "confidence": { "enum": ["high", "medium"] }
351
+ }
352
+ }
353
+ }
354
+ }
355
+ }
356
+ },
357
+ "baseline": {
358
+ "description": "The baseline the scan was compared with (§11, §15): its path as given, its header, and scan-level notes such as version skew (§4). Null without a baseline.",
359
+ "oneOf": [
360
+ { "type": "null" },
361
+ {
362
+ "type": "object",
363
+ "required": ["path", "header", "notes"],
364
+ "additionalProperties": false,
365
+ "properties": {
366
+ "path": { "type": "string" },
367
+ "header": {
368
+ "description": "The baseline's header as this monkeypatchlist reads it: an older formatVersion or fingerprint scheme has been migrated in memory, and a version-skew note names the versions the file was written with.",
369
+ "type": "object",
370
+ "required": [
371
+ "formatVersion",
372
+ "scanConfigId",
373
+ "fingerprintScheme",
374
+ "catalogVersion",
375
+ "monkeypatchlistVersion",
376
+ "completeness",
377
+ "surface",
378
+ "packages"
379
+ ],
380
+ "additionalProperties": false,
381
+ "properties": {
382
+ "formatVersion": { "type": "integer", "minimum": 1 },
383
+ "scanConfigId": { "type": "string" },
384
+ "fingerprintScheme": { "type": "integer", "minimum": 1 },
385
+ "catalogVersion": { "type": "integer", "minimum": 1 },
386
+ "monkeypatchlistVersion": { "type": "string" },
387
+ "completeness": {
388
+ "description": "The completeness level the baseline was written under (§13).",
389
+ "enum": ["complete", "complete-with-limitations", "incomplete"]
390
+ },
391
+ "surface": { "enum": ["protected", "all"] },
392
+ "packages": {
393
+ "description": "Name → version and version source, strong versions only (§10).",
394
+ "type": "object",
395
+ "additionalProperties": {
396
+ "type": "object",
397
+ "required": ["version", "versionSource"],
398
+ "additionalProperties": false,
399
+ "properties": { "version": { "type": "string" }, "versionSource": { "type": "string" } }
400
+ }
401
+ }
402
+ }
403
+ },
404
+ "notes": {
405
+ "description": "Scan-level notes on the baseline. `version-skew` (§4): the baseline was written with another monkeypatchlist version, catalog version, formatVersion or fingerprint scheme.",
406
+ "type": "array",
407
+ "items": { "$ref": "#/$defs/versionSkew" }
408
+ }
409
+ }
410
+ }
411
+ ]
412
+ },
413
+ "packages": {
414
+ "description": "The same map the baseline stores (§11, §15): each finding's containing package, by name, with its strong version and that version's source (§10 Version: `store-path`, or `lockfile`). A name with no strong version, or with more than one strong version in the scan, has no entry.",
415
+ "type": "object",
416
+ "additionalProperties": {
417
+ "type": "object",
418
+ "required": ["version", "versionSource"],
419
+ "additionalProperties": false,
420
+ "properties": { "version": { "type": "string" }, "versionSource": { "enum": ["store-path", "lockfile"] } }
421
+ }
422
+ },
423
+ "findings": { "type": "array", "items": { "$ref": "#/$defs/finding" } },
424
+ "ineffectiveWrites": { "type": "array", "items": { "$ref": "#/$defs/ineffectiveWrite" } },
425
+ "artifacts": { "type": "array", "items": { "$ref": "#/$defs/artifact" } },
426
+ "run": {
427
+ "description": "All wall-clock data. Nothing outside this block varies between runs over the same inputs.",
428
+ "type": "object",
429
+ "required": ["startedAt", "durationMs", "retrievals"],
430
+ "additionalProperties": false,
431
+ "properties": {
432
+ "startedAt": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$" },
433
+ "durationMs": { "type": "integer", "minimum": 0 },
434
+ "retrievals": {
435
+ "description": "The wall-clock facts of each fetch, by requested URL (§17 What is recorded). A URL skipped offline was never fetched, so it has none, and nor has one the safety floor refused before any response.",
436
+ "type": "object",
437
+ "additionalProperties": {
438
+ "type": "object",
439
+ "required": ["fetchedAt", "etag", "lastModified"],
440
+ "additionalProperties": false,
441
+ "properties": {
442
+ "fetchedAt": {
443
+ "description": "When the fetch finished.",
444
+ "type": "string",
445
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
446
+ },
447
+ "etag": { "description": "The final response's ETag, or null without one.", "type": ["string", "null"] },
448
+ "lastModified": {
449
+ "description": "The final response's Last-Modified, or null without one.",
450
+ "type": ["string", "null"]
451
+ }
452
+ }
453
+ }
454
+ }
455
+ }
456
+ }
457
+ },
458
+ "$defs": {
459
+ "failOn": {
460
+ "description": "The baseline states the gate fails on (--fail-on), in the order added, changed. removed and unconfirmed can't gate.",
461
+ "type": "array",
462
+ "uniqueItems": true,
463
+ "items": { "enum": ["added", "changed"] }
464
+ },
465
+ "realm": { "enum": ["window", "dedicated-worker", "shared-worker", "service-worker"] },
466
+ "realmInstance": { "enum": ["current", "other", "unknown"] },
467
+ "reachability": {
468
+ "description": "Whether a platform mutation happens, judged by the guards on its path (§7 Values): `unconditional` (no guard that matters), `guarded-native-absence` (it runs only when some native, not necessarily the target, is missing), `conditional` (a recognized guard that can't be decided statically) or `unknown` (control flow the analyzer couldn't model). Not identity, and in R1 it doesn't make a finding `changed` (§11).",
469
+ "enum": ["unconditional", "guarded-native-absence", "conditional", "unknown"]
470
+ },
471
+ "reachabilityBasis": {
472
+ "description": "How an occurrence's reachability was judged (§7 Where reachability is judged from): `call-path`, along resolved calls out to its install entry, or `creation-site`, from where a function no resolved call reaches was created. Evidence: it decides nothing in R1.",
473
+ "enum": ["call-path", "creation-site"]
474
+ },
475
+ "installContext": {
476
+ "description": "Whether a mutation runs at load or later (§7 Install context): `load` when a resolved synchronous chain reaches top-level code, `deferred` when only a later call of its install entry reaches it. Not identity, and in R1 it doesn't make a finding `changed` (§11).",
477
+ "enum": ["load", "deferred"]
478
+ },
479
+ "installEntry": {
480
+ "description": "The name of the install entry a `deferred` occurrence waits on, e.g. `init` (§7 Install context): the function's own name, else the variable, member, property or method it is bound to where it is created. Null for a `load` occurrence, and for an entry with no name, such as an anonymous callback.",
481
+ "oneOf": [{ "type": "null" }, { "type": "string" }]
482
+ },
483
+ "origin": { "enum": ["local-build", "same-origin", "cross-origin", "inline"] },
484
+ "changeRecord": {
485
+ "description": "A catalog changelog record (§4 Catalog versions). `target`: a target added, or dropped (deliberately, or by an exclusion). `protected-entry`: a protected-surface entry gained or lost, with the targets it names. `member-data`: a target's descriptor or assign kind changed (a member entering or leaving an enumeration is one of these or a `target` record). `holder`: a holder added, dropped or re-chained, with its prototype on each side. `immutable-prototype`: a holder's immutablePrototype flag flipped. `framework-path-rule` (§10) and `url-normalization` (§11): a rule added, removed or changed, by id; a URL normalization step that is no path rule has the id `scheme`, `host` or `drop`.",
486
+ "oneOf": [
487
+ {
488
+ "type": "object",
489
+ "required": [
490
+ "catalogVersion",
491
+ "kind",
492
+ "change",
493
+ "realm",
494
+ "name"
495
+ ],
496
+ "additionalProperties": false,
497
+ "properties": {
498
+ "catalogVersion": {
499
+ "type": "integer",
500
+ "minimum": 2
501
+ },
502
+ "kind": {
503
+ "const": "target"
504
+ },
505
+ "change": {
506
+ "enum": [
507
+ "added",
508
+ "dropped"
509
+ ]
510
+ },
511
+ "realm": {
512
+ "$ref": "#/$defs/realm"
513
+ },
514
+ "name": {
515
+ "type": "string"
516
+ }
517
+ }
518
+ },
519
+ {
520
+ "type": "object",
521
+ "required": [
522
+ "catalogVersion",
523
+ "kind",
524
+ "change",
525
+ "surface",
526
+ "entry"
527
+ ],
528
+ "additionalProperties": false,
529
+ "properties": {
530
+ "catalogVersion": {
531
+ "type": "integer",
532
+ "minimum": 2
533
+ },
534
+ "kind": {
535
+ "const": "protected-entry"
536
+ },
537
+ "change": {
538
+ "enum": [
539
+ "gained",
540
+ "lost"
541
+ ]
542
+ },
543
+ "surface": {
544
+ "enum": [
545
+ "networking",
546
+ "events",
547
+ "scheduling",
548
+ "navigation",
549
+ "storage",
550
+ "crypto",
551
+ "DOM",
552
+ "ECMAScript",
553
+ "diagnostics",
554
+ "workers",
555
+ "other"
556
+ ]
557
+ },
558
+ "entry": {
559
+ "type": "object",
560
+ "required": [
561
+ "interface",
562
+ "targets"
563
+ ],
564
+ "properties": {
565
+ "interface": {
566
+ "type": "string"
567
+ },
568
+ "member": {
569
+ "type": "string"
570
+ },
571
+ "workerEquivalent": {
572
+ "type": "string"
573
+ },
574
+ "targets": {
575
+ "type": "object"
576
+ }
577
+ },
578
+ "additionalProperties": false
579
+ }
580
+ }
581
+ },
582
+ {
583
+ "type": "object",
584
+ "required": [
585
+ "catalogVersion",
586
+ "kind",
587
+ "realm",
588
+ "name",
589
+ "before",
590
+ "after"
591
+ ],
592
+ "additionalProperties": false,
593
+ "properties": {
594
+ "catalogVersion": {
595
+ "type": "integer",
596
+ "minimum": 2
597
+ },
598
+ "kind": {
599
+ "const": "member-data"
600
+ },
601
+ "realm": {
602
+ "$ref": "#/$defs/realm"
603
+ },
604
+ "name": {
605
+ "type": "string"
606
+ },
607
+ "before": {
608
+ "type": "object",
609
+ "required": [
610
+ "descriptor"
611
+ ],
612
+ "additionalProperties": false,
613
+ "properties": {
614
+ "descriptor": {
615
+ "type": "object"
616
+ },
617
+ "assign": {
618
+ "enum": [
619
+ "setter",
620
+ "put-forwards",
621
+ "event-handler",
622
+ "replaceable",
623
+ "lenient-setter",
624
+ "readonly"
625
+ ]
626
+ }
627
+ }
628
+ },
629
+ "after": {
630
+ "type": "object",
631
+ "required": [
632
+ "descriptor"
633
+ ],
634
+ "additionalProperties": false,
635
+ "properties": {
636
+ "descriptor": {
637
+ "type": "object"
638
+ },
639
+ "assign": {
640
+ "enum": [
641
+ "setter",
642
+ "put-forwards",
643
+ "event-handler",
644
+ "replaceable",
645
+ "lenient-setter",
646
+ "readonly"
647
+ ]
648
+ }
649
+ }
650
+ }
651
+ }
652
+ },
653
+ {
654
+ "type": "object",
655
+ "required": [
656
+ "catalogVersion",
657
+ "kind",
658
+ "change",
659
+ "realm",
660
+ "holder"
661
+ ],
662
+ "additionalProperties": false,
663
+ "properties": {
664
+ "catalogVersion": {
665
+ "type": "integer",
666
+ "minimum": 2
667
+ },
668
+ "kind": {
669
+ "const": "holder"
670
+ },
671
+ "change": {
672
+ "enum": [
673
+ "added",
674
+ "dropped",
675
+ "rechained"
676
+ ]
677
+ },
678
+ "realm": {
679
+ "$ref": "#/$defs/realm"
680
+ },
681
+ "holder": {
682
+ "type": "string"
683
+ },
684
+ "before": {
685
+ "type": "object",
686
+ "required": [
687
+ "proto"
688
+ ],
689
+ "additionalProperties": false,
690
+ "properties": {
691
+ "proto": {
692
+ "type": [
693
+ "string",
694
+ "null"
695
+ ]
696
+ }
697
+ }
698
+ },
699
+ "after": {
700
+ "type": "object",
701
+ "required": [
702
+ "proto"
703
+ ],
704
+ "additionalProperties": false,
705
+ "properties": {
706
+ "proto": {
707
+ "type": [
708
+ "string",
709
+ "null"
710
+ ]
711
+ }
712
+ }
713
+ }
714
+ }
715
+ },
716
+ {
717
+ "type": "object",
718
+ "required": [
719
+ "catalogVersion",
720
+ "kind",
721
+ "realm",
722
+ "holder",
723
+ "before",
724
+ "after"
725
+ ],
726
+ "additionalProperties": false,
727
+ "properties": {
728
+ "catalogVersion": {
729
+ "type": "integer",
730
+ "minimum": 2
731
+ },
732
+ "kind": {
733
+ "const": "immutable-prototype"
734
+ },
735
+ "realm": {
736
+ "$ref": "#/$defs/realm"
737
+ },
738
+ "holder": {
739
+ "type": "string"
740
+ },
741
+ "before": {
742
+ "type": "boolean"
743
+ },
744
+ "after": {
745
+ "type": "boolean"
746
+ }
747
+ }
748
+ },
749
+ {
750
+ "type": "object",
751
+ "required": [
752
+ "catalogVersion",
753
+ "kind",
754
+ "change",
755
+ "id"
756
+ ],
757
+ "additionalProperties": false,
758
+ "properties": {
759
+ "catalogVersion": {
760
+ "type": "integer",
761
+ "minimum": 2
762
+ },
763
+ "kind": {
764
+ "const": "framework-path-rule"
765
+ },
766
+ "change": {
767
+ "enum": [
768
+ "added",
769
+ "removed",
770
+ "changed"
771
+ ]
772
+ },
773
+ "id": {
774
+ "type": "string"
775
+ },
776
+ "before": {
777
+ "type": "object"
778
+ },
779
+ "after": {
780
+ "type": "object"
781
+ }
782
+ }
783
+ },
784
+ {
785
+ "type": "object",
786
+ "required": [
787
+ "catalogVersion",
788
+ "kind",
789
+ "change",
790
+ "id"
791
+ ],
792
+ "additionalProperties": false,
793
+ "properties": {
794
+ "catalogVersion": {
795
+ "type": "integer",
796
+ "minimum": 2
797
+ },
798
+ "kind": {
799
+ "const": "url-normalization"
800
+ },
801
+ "change": {
802
+ "enum": [
803
+ "added",
804
+ "removed",
805
+ "changed"
806
+ ]
807
+ },
808
+ "id": {
809
+ "type": "string"
810
+ },
811
+ "before": {},
812
+ "after": {}
813
+ }
814
+ }
815
+ ]
816
+ },
817
+ "finding": {
818
+ "type": "object",
819
+ "required": [
820
+ "fingerprint",
821
+ "targetKey",
822
+ "target",
823
+ "surface",
824
+ "effect",
825
+ "locks",
826
+ "attribution",
827
+ "reachability",
828
+ "reachabilityBasis",
829
+ "installContext",
830
+ "confidence",
831
+ "baselineState",
832
+ "matchedBy",
833
+ "changedReasons",
834
+ "notes",
835
+ "policy",
836
+ "occurrences"
837
+ ],
838
+ "additionalProperties": false,
839
+ "properties": {
840
+ "fingerprint": { "type": "string", "description": "realm|target|effect|attribution key (§11)" },
841
+ "targetKey": { "type": "string", "description": "realm|target|effect (§11)" },
842
+ "target": {
843
+ "type": "object",
844
+ "required": ["realm", "holder", "name"],
845
+ "additionalProperties": false,
846
+ "properties": {
847
+ "realm": { "$ref": "#/$defs/realm" },
848
+ "holder": { "enum": ["global", "constructor", "prototype", "instance", "namespace"] },
849
+ "name": { "type": "string" },
850
+ "shadows": {
851
+ "description": "For a shadowing write, the inherited member the written object's new own property shadows (§3, ADR 0002). Derived from the catalog; not identity.",
852
+ "type": "string"
853
+ }
854
+ }
855
+ },
856
+ "surface": {
857
+ "enum": [
858
+ "networking",
859
+ "events",
860
+ "scheduling",
861
+ "navigation",
862
+ "storage",
863
+ "crypto",
864
+ "DOM",
865
+ "ECMAScript",
866
+ "diagnostics",
867
+ "workers",
868
+ "other"
869
+ ]
870
+ },
871
+ "effect": { "enum": ["replace", "wrap", "add", "delete", "descriptor-change", "prototype-change"] },
872
+ "locks": {
873
+ "description": "Whether the mutation leaves the target non-configurable or non-writable (§8): `unknown` when the resolver can't tell. A finding takes its most-locking occurrence's: `true` over `unknown` over `false`.",
874
+ "enum": [true, false, "unknown"]
875
+ },
876
+ "attribution": {
877
+ "description": "The attribution key (§11) and the provenance that follows from it (§10). `package` is the containing package's name, for a `pkg:` key. `vendoredBy` is the vendoring package (`name@version`) when every occurrence is vendored code by that one package (a store-name mismatch, or a package the lockfile says isn't installed, §10 Provenance): evidence only, never in the fingerprint, the baseline or `changed`. `workspace` is the lockfile workspace (`name@version`) of first-party code, when every occurrence names that one (§10 Provenance, ADR 0006): evidence only, given only with --lockfile.",
878
+ "type": "object",
879
+ "required": ["key", "provenance"],
880
+ "additionalProperties": false,
881
+ "properties": {
882
+ "key": { "type": "string" },
883
+ "provenance": { "enum": ["first-party", "bundled-dependency", "remote", "inline", "unknown"] },
884
+ "package": { "type": "string" },
885
+ "vendoredBy": { "type": "string" },
886
+ "workspace": { "type": "string" }
887
+ }
888
+ },
889
+ "introducedBy": {
890
+ "description": "The union of the occurrences' introducing dependencies (§10), `name@version`, sorted; absent when no occurrence has them. Evidence only: never in the fingerprint, the baseline or `changed`.",
891
+ "type": "array",
892
+ "items": { "type": "string" }
893
+ },
894
+ "reachability": {
895
+ "description": "The most-reaching over the finding's occurrences (§7): `unconditional` over `conditional` over `unknown` over `guarded-native-absence`. Null for a `removed` or `unconfirmed` baseline entry, which has no occurrences.",
896
+ "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/reachability" }]
897
+ },
898
+ "reachabilityBasis": {
899
+ "description": "The basis of the occurrences that give the finding's reachability (§7): `call-path` when any of them is `call-path`, otherwise `creation-site`. Evidence: it decides nothing in R1. Null for a `removed` or `unconfirmed` baseline entry, which has no occurrences.",
900
+ "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/reachabilityBasis" }]
901
+ },
902
+ "installContext": {
903
+ "description": "`load` if any of the finding's occurrences is `load`, else `deferred` (§7). Null for a `removed` or `unconfirmed` baseline entry, which has no occurrences.",
904
+ "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/installContext" }]
905
+ },
906
+ "confidence": {
907
+ "description": "The highest level per dimension across the finding's occurrences, with the reasons of the occurrences at that level (§9). Null for a `removed` or `unconfirmed` baseline entry, which has no occurrences.",
908
+ "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/confidence" }]
909
+ },
910
+ "baselineState": {
911
+ "description": "How the finding compares with the baseline (§11). Null without a baseline. A `removed` or `unconfirmed` finding is a baseline entry the scan didn't find: it carries the entry's readable context and no occurrences.",
912
+ "enum": ["added", "existing", "changed", "removed", "unconfirmed", null]
913
+ },
914
+ "matchedBy": {
915
+ "description": "The matching pass that paired the finding with a baseline entry (§11), or null when none did.",
916
+ "enum": ["fingerprint", "effect", "target-key", null]
917
+ },
918
+ "changedReasons": {
919
+ "description": "Before (the baseline entry's value) → after (the finding's) for each reason the finding is `changed` (§11). Empty unless it is `changed`.",
920
+ "type": "array",
921
+ "items": {
922
+ "oneOf": [
923
+ {
924
+ "type": "object",
925
+ "required": ["reason", "before", "after"],
926
+ "additionalProperties": false,
927
+ "properties": {
928
+ "reason": { "const": "attribution" },
929
+ "before": { "type": "string", "description": "The baseline entry's attribution key." },
930
+ "after": { "type": "string", "description": "The finding's attribution key." }
931
+ }
932
+ },
933
+ {
934
+ "type": "object",
935
+ "required": ["reason", "before", "after"],
936
+ "additionalProperties": false,
937
+ "properties": {
938
+ "reason": { "const": "effect" },
939
+ "before": { "$ref": "#/$defs/finding/properties/effect" },
940
+ "after": { "$ref": "#/$defs/finding/properties/effect" }
941
+ }
942
+ },
943
+ {
944
+ "type": "object",
945
+ "required": ["reason", "before", "after"],
946
+ "additionalProperties": false,
947
+ "properties": {
948
+ "reason": { "const": "locks" },
949
+ "before": { "type": "boolean" },
950
+ "after": { "type": "boolean" }
951
+ }
952
+ }
953
+ ]
954
+ }
955
+ },
956
+ "notes": {
957
+ "description": "Notes on how the finding was matched (§11). `rekeyed`: the target-key pass paired it across `unknown`, from the paired baseline entries' attribution keys to its own. `shared-target-key`: it stays `added` or `removed` because its target-key group is ambiguous; `fingerprints` are the other side's known keys it could have paired with. `previous-version` (§11 `previousVersion`): the containing package has a strong version in both the baseline's and the scan's `packages` map and they differ, from the baseline's (`before`) to the scan's (`after`), in any state. `reachability-change` and `install-context-change` (§11 Never `changed`): on an `existing` or `changed` finding, the previous scan (--previous, or a full report as --baseline) gave a baseline entry it paired with another value, from that value (`before`) to the finding's (`after`), one note per distinct previous value. They never decide a state or trip the gate.",
958
+ "type": "array",
959
+ "items": {
960
+ "oneOf": [
961
+ {
962
+ "type": "object",
963
+ "required": ["kind", "before", "after"],
964
+ "additionalProperties": false,
965
+ "properties": {
966
+ "kind": { "const": "rekeyed" },
967
+ "before": { "type": "array", "items": { "type": "string" } },
968
+ "after": { "type": "string" }
969
+ }
970
+ },
971
+ {
972
+ "type": "object",
973
+ "required": ["kind", "fingerprints"],
974
+ "additionalProperties": false,
975
+ "properties": {
976
+ "kind": { "const": "shared-target-key" },
977
+ "fingerprints": { "type": "array", "items": { "type": "string" } }
978
+ }
979
+ },
980
+ {
981
+ "type": "object",
982
+ "required": ["kind", "package", "before", "after"],
983
+ "additionalProperties": false,
984
+ "properties": {
985
+ "kind": { "const": "previous-version" },
986
+ "package": { "type": "string" },
987
+ "before": { "type": "string" },
988
+ "after": { "type": "string" }
989
+ }
990
+ },
991
+ {
992
+ "type": "object",
993
+ "required": ["kind", "before", "after"],
994
+ "additionalProperties": false,
995
+ "properties": {
996
+ "kind": { "const": "reachability-change" },
997
+ "before": { "$ref": "#/$defs/reachability" },
998
+ "after": { "$ref": "#/$defs/reachability" }
999
+ }
1000
+ },
1001
+ {
1002
+ "type": "object",
1003
+ "required": ["kind", "before", "after"],
1004
+ "additionalProperties": false,
1005
+ "properties": {
1006
+ "kind": { "const": "install-context-change" },
1007
+ "before": { "$ref": "#/$defs/installContext" },
1008
+ "after": { "$ref": "#/$defs/installContext" }
1009
+ }
1010
+ }
1011
+ ]
1012
+ }
1013
+ },
1014
+ "catalogStatus": {
1015
+ "description": "Set on a finding whose target, or the member it shadows, is a retained target (§4 Catalog versions): one upstream removed that the catalog keeps. Information only.",
1016
+ "const": "retained"
1017
+ },
1018
+ "explainedBy": {
1019
+ "description": "The catalog changelog's records that could explain this delta (§4 Catalog versions): changes between the baseline's catalogVersion and the scan's that name its target, the member it shadows on either side, or a wildcard's holder, as the §4 table matches them. Each record carries the catalog version that made the change. Only an offered explanation: it never decides a state. Absent when no record applies, and never set on `unconfirmed` or on `existing` without a `rekeyed` note. Never baselined.",
1020
+ "type": "array",
1021
+ "minItems": 1,
1022
+ "items": {
1023
+ "$ref": "#/$defs/changeRecord"
1024
+ }
1025
+ },
1026
+ "policy": {
1027
+ "oneOf": [
1028
+ { "type": "null" },
1029
+ {
1030
+ "type": "object",
1031
+ "required": ["outcome", "by"],
1032
+ "additionalProperties": false,
1033
+ "properties": {
1034
+ "outcome": { "const": "fail" },
1035
+ "by": { "description": "The --fail-on state the finding is in.", "enum": ["fail-on:added", "fail-on:changed"] }
1036
+ }
1037
+ }
1038
+ ]
1039
+ },
1040
+ "occurrences": { "type": "array", "items": { "$ref": "#/$defs/occurrence" } }
1041
+ }
1042
+ },
1043
+ "occurrence": {
1044
+ "type": "object",
1045
+ "required": [
1046
+ "artifact",
1047
+ "generated",
1048
+ "original",
1049
+ "mechanism",
1050
+ "reachability",
1051
+ "reachabilityBasis",
1052
+ "installContext",
1053
+ "installEntry",
1054
+ "realmInstance",
1055
+ "evidence",
1056
+ "confidence",
1057
+ "trace"
1058
+ ],
1059
+ "additionalProperties": false,
1060
+ "properties": {
1061
+ "artifact": {
1062
+ "type": "object",
1063
+ "required": ["url", "hash", "origin"],
1064
+ "additionalProperties": false,
1065
+ "properties": {
1066
+ "url": { "type": "string" },
1067
+ "hash": { "type": "string" },
1068
+ "origin": { "$ref": "#/$defs/origin" }
1069
+ }
1070
+ },
1071
+ "generated": {
1072
+ "description": "The write site in the artifact (§5).",
1073
+ "$ref": "#/$defs/location"
1074
+ },
1075
+ "original": {
1076
+ "description": "The original location the artifact's source map resolves for the write's lookup point (§10), or null when there is none: no map, an unmapped position, a synthetic or bundler-runtime source, or a position a failed token check discarded.",
1077
+ "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/originalLocation" }]
1078
+ },
1079
+ "mechanism": {
1080
+ "enum": [
1081
+ "assign",
1082
+ "define-property",
1083
+ "define-properties",
1084
+ "reflect-define",
1085
+ "bulk-assign",
1086
+ "delete",
1087
+ "set-prototype",
1088
+ "declare"
1089
+ ]
1090
+ },
1091
+ "reachability": { "$ref": "#/$defs/reachability" },
1092
+ "reachabilityBasis": { "$ref": "#/$defs/reachabilityBasis" },
1093
+ "installContext": { "$ref": "#/$defs/installContext" },
1094
+ "installEntry": { "$ref": "#/$defs/installEntry" },
1095
+ "realmInstance": {
1096
+ "description": "Whether the write reaches the artifact's own global object (`current`), another window's (`other`), or one the analyzer can't tell (`unknown`) (§4 Other windows). Evidence, never identity.",
1097
+ "$ref": "#/$defs/realmInstance"
1098
+ },
1099
+ "evidence": {
1100
+ "description": "The occurrence's attribution evidence (§8, §10), each field only when it applies: `source`, the raw `sources` entry of a synthetic or bundler-runtime source the lookup reached (null for a null entry); `rejected`, the lookup candidate a failed token check discarded; `slug`, the lossy slug that names a scoped package under Yarn's pnpm linker; `pathRule`, the id of the framework path rule that named the package of an escaped source; `package`, the package a remote artifact's source map names at the occurrence, which is evidence only, as remote code keys url: (§9, §10); `vendoredBy`, the vendoring package (`name@version`) when the containing package's path lies inside another package's store entry (a store-name mismatch), or inside an installed package when the lockfile says it isn't installed itself (§10 Provenance), evidence only; `version`, the containing package's version (§10 Version); `workspace`, the lockfile workspace (`name@version`) that holds first-party code, which only a lockfile gives (§10 Provenance).",
1101
+ "type": "object",
1102
+ "additionalProperties": false,
1103
+ "properties": {
1104
+ "source": { "type": ["string", "null"] },
1105
+ "rejected": { "$ref": "#/$defs/originalLocation" },
1106
+ "slug": { "type": "string" },
1107
+ "pathRule": { "type": "string" },
1108
+ "package": { "type": "string" },
1109
+ "vendoredBy": { "type": "string" },
1110
+ "version": {
1111
+ "description": "The containing package's version, from its strongest source (§10 Version), evidence only: `store-path` and `lockfile` are strong; `package-json` (its package.json in sourcesContent), `version-constant` (an in-package VERSION constant) and `banner` are weak content signals, which never reach `packages` or `previousVersion`.",
1112
+ "type": "object",
1113
+ "required": ["version", "versionSource"],
1114
+ "additionalProperties": false,
1115
+ "properties": {
1116
+ "version": { "type": "string" },
1117
+ "versionSource": { "enum": ["store-path", "lockfile", "package-json", "version-constant", "banner"] }
1118
+ }
1119
+ },
1120
+ "workspace": { "type": "string" }
1121
+ }
1122
+ },
1123
+ "introducedBy": {
1124
+ "description": "The occurrence's introducing dependencies (§10): the direct dependencies of the scanned application whose installed tree includes the containing package, `name@version`, sorted. Present only for bundled-dependency code a usable lockfile places; absent when they are unknown.",
1125
+ "type": "array",
1126
+ "items": { "type": "string" }
1127
+ },
1128
+ "confidence": { "$ref": "#/$defs/confidence" },
1129
+ "trace": { "type": "array", "items": { "$ref": "#/$defs/traceStep" } }
1130
+ }
1131
+ },
1132
+ "ineffectiveWrite": {
1133
+ "description": "The writes that can't change one target, for one reason (§3 Record): one record per (realm, target, reason). Never a finding: no fingerprint, baseline state or effect of its own. `surface` is the target's, as a finding's.",
1134
+ "type": "object",
1135
+ "required": ["target", "surface", "reason", "occurrences"],
1136
+ "additionalProperties": false,
1137
+ "properties": {
1138
+ "target": { "$ref": "#/$defs/finding/properties/target" },
1139
+ "surface": { "$ref": "#/$defs/finding/properties/surface" },
1140
+ "reason": { "enum": ["readonly", "lenient-setter", "non-writable", "non-configurable", "immutable-prototype"] },
1141
+ "occurrences": { "type": "array", "items": { "$ref": "#/$defs/ineffectiveOccurrence" } }
1142
+ }
1143
+ },
1144
+ "ineffectiveOccurrence": {
1145
+ "description": "An occurrence of an ineffective write (§3 Record): its location and attribution, as a finding's occurrence has them, with the effect it intended, its mechanism, the strictness of its code, and `throws`: `always` in sloppy and strict code alike, `strict-only`, or `never`.",
1146
+ "type": "object",
1147
+ "required": [
1148
+ "artifact",
1149
+ "generated",
1150
+ "original",
1151
+ "effect",
1152
+ "mechanism",
1153
+ "reachability",
1154
+ "reachabilityBasis",
1155
+ "installContext",
1156
+ "installEntry",
1157
+ "strictness",
1158
+ "throws",
1159
+ "realmInstance",
1160
+ "attribution",
1161
+ "evidence",
1162
+ "trace"
1163
+ ],
1164
+ "additionalProperties": false,
1165
+ "properties": {
1166
+ "artifact": { "$ref": "#/$defs/occurrence/properties/artifact" },
1167
+ "generated": { "$ref": "#/$defs/location" },
1168
+ "original": { "$ref": "#/$defs/occurrence/properties/original" },
1169
+ "effect": { "$ref": "#/$defs/finding/properties/effect" },
1170
+ "mechanism": { "$ref": "#/$defs/occurrence/properties/mechanism" },
1171
+ "reachability": { "$ref": "#/$defs/reachability" },
1172
+ "reachabilityBasis": { "$ref": "#/$defs/reachabilityBasis" },
1173
+ "installContext": { "$ref": "#/$defs/installContext" },
1174
+ "installEntry": { "$ref": "#/$defs/installEntry" },
1175
+ "strictness": { "enum": ["sloppy", "strict"] },
1176
+ "throws": { "enum": ["always", "strict-only", "never"] },
1177
+ "realmInstance": { "$ref": "#/$defs/realmInstance" },
1178
+ "attribution": { "$ref": "#/$defs/finding/properties/attribution" },
1179
+ "evidence": { "$ref": "#/$defs/occurrence/properties/evidence" },
1180
+ "trace": { "type": "array", "items": { "$ref": "#/$defs/traceStep" } }
1181
+ }
1182
+ },
1183
+ "confidence": {
1184
+ "description": "Analytical certainty, never risk, for each of three dimensions (§9). A level below high carries its reasons from the dimension's closed list; the level is the lowest among them.",
1185
+ "type": "object",
1186
+ "required": ["target", "mutation", "attribution"],
1187
+ "additionalProperties": false,
1188
+ "properties": {
1189
+ "target": {
1190
+ "$ref": "#/$defs/dimension",
1191
+ "type": "object",
1192
+ "properties": {
1193
+ "reasons": {
1194
+ "type": "array",
1195
+ "items": {
1196
+ "enum": ["realm-assumed", "holder-alternatives", "member-alternatives", "direct-eval-scope", "with-scope"]
1197
+ }
1198
+ }
1199
+ }
1200
+ },
1201
+ "mutation": {
1202
+ "$ref": "#/$defs/dimension",
1203
+ "type": "object",
1204
+ "properties": {
1205
+ "reasons": {
1206
+ "type": "array",
1207
+ "items": { "enum": ["outcome-undecidable", "wildcard-outcome-mixed", "const-collision"] }
1208
+ }
1209
+ }
1210
+ },
1211
+ "attribution": {
1212
+ "$ref": "#/$defs/dimension",
1213
+ "type": "object",
1214
+ "properties": {
1215
+ "reasons": {
1216
+ "type": "array",
1217
+ "items": {
1218
+ "enum": [
1219
+ "token-check-n/a",
1220
+ "sidecar-not-token-verified",
1221
+ "framework-path-rule",
1222
+ "first-party-inferred",
1223
+ "prebundled-dist",
1224
+ "yarn-slug",
1225
+ "line-separator",
1226
+ "no-map",
1227
+ "escaped-source",
1228
+ "token-check-failed",
1229
+ "vendored",
1230
+ "foreign-scheme",
1231
+ "ignore-list-demoted"
1232
+ ]
1233
+ }
1234
+ }
1235
+ }
1236
+ }
1237
+ }
1238
+ },
1239
+ "dimension": {
1240
+ "description": "One dimension's level, and the reasons that hold it below high: none at high, at least one otherwise.",
1241
+ "type": "object",
1242
+ "required": ["level", "reasons"],
1243
+ "unevaluatedProperties": false,
1244
+ "properties": {
1245
+ "level": { "enum": ["high", "medium", "low"] },
1246
+ "reasons": { "type": "array", "uniqueItems": true }
1247
+ },
1248
+ "if": { "properties": { "level": { "const": "high" } } },
1249
+ "then": { "properties": { "reasons": { "type": "array", "maxItems": 0 } } },
1250
+ "else": { "properties": { "reasons": { "type": "array", "minItems": 1 } } }
1251
+ },
1252
+ "originalLocation": {
1253
+ "description": "A position in an original source (§10): the raw `sources` entry of the artifact's source map, a 1-based line and a 0-based column.",
1254
+ "type": "object",
1255
+ "required": ["source", "line", "column"],
1256
+ "additionalProperties": false,
1257
+ "properties": {
1258
+ "source": { "type": "string" },
1259
+ "line": { "type": "integer", "minimum": 1 },
1260
+ "column": { "type": "integer", "minimum": 0 }
1261
+ }
1262
+ },
1263
+ "location": {
1264
+ "description": "A position in an artifact's generated code: a UTF-16 range [start, end), and its start as a 1-based line and 0-based column (§5).",
1265
+ "type": "object",
1266
+ "required": ["start", "end", "line", "column"],
1267
+ "additionalProperties": false,
1268
+ "properties": {
1269
+ "start": { "type": "integer", "minimum": 0 },
1270
+ "end": { "type": "integer", "minimum": 0 },
1271
+ "line": { "type": "integer", "minimum": 1 },
1272
+ "column": { "type": "integer", "minimum": 0 }
1273
+ }
1274
+ },
1275
+ "traceStep": {
1276
+ "description": "One step of a resolution trace (§14). `kind` comes from a closed list; each kind carries its own fields and no others, and `text` is a rendered sentence.",
1277
+ "type": "object",
1278
+ "required": ["kind", "text"],
1279
+ "unevaluatedProperties": false,
1280
+ "properties": {
1281
+ "kind": {
1282
+ "enum": [
1283
+ "binding",
1284
+ "alias",
1285
+ "fold",
1286
+ "call",
1287
+ "module-link",
1288
+ "catalog-holder",
1289
+ "enumeration",
1290
+ "guard",
1291
+ "prune",
1292
+ "creation-site",
1293
+ "outcome",
1294
+ "restore",
1295
+ "token-check",
1296
+ "path-rule",
1297
+ "confidence-reason",
1298
+ "note"
1299
+ ]
1300
+ },
1301
+ "artifact": {
1302
+ "description": "The URL of the artifact the step's `generated` location (for a `token-check` step, its `lookup`) is in, when it isn't the occurrence's own: another member of the occurrence's link group (§6 Link groups). A `module-link` step always names its artifact.",
1303
+ "type": "string"
1304
+ },
1305
+ "text": { "type": "string" }
1306
+ },
1307
+ "allOf": [
1308
+ {
1309
+ "if": { "properties": { "kind": { "const": "binding" } } },
1310
+ "then": {
1311
+ "description": "How a name resolved: `global` (no declaration: the global object's property), `alias` (no declaration, and the name is an alias of the holder in `aliasOf`), or `declaration` (a declaration that binds the global object's property). `form` is the syntactic form the global object was recognized in (§5 Global resolution): `global-property` (a bare global, constructor, namespace or platform singleton; `holds` names the native holder its value is: the catalog's, or the singleton), `global-name` (`window`, `self`, `globalThis`, and a window's `frames`), `guarded-global` (a `typeof`-guarded `global`), `top-level-this`, `function-return-this`, `sloppy-this` (`this` in a sloppy function a call the analyzer evaluates calls without a `this`, or with `null` or `undefined`), `other-window` (a window reached from another value: `parent`, `top` or `opener` of a window, a child window read from a window by a constant index (`window[0]`) or, from a window spelled as the frames collection, by any index (`frames[i]`), named by the index in brackets (`[0]`, `[i]`), or `defaultView` or `contentWindow` of any object; this window's `document.defaultView` and a child's `parent` of this window are this window; `aliasOf` is the realm's global interface) or `singleton` (a platform singleton read through the access `path` its alias group lists; `aliasOf` is its canonical path). `realmInstance` is the window the name's value belongs to (§4 Other windows). `chain` locates the outermost `?:`, `||`, `&&` or `??` chain it was selected through.",
1312
+ "required": ["name", "resolution", "form", "realm", "realmInstance"],
1313
+ "properties": {
1314
+ "name": { "type": "string" },
1315
+ "resolution": { "enum": ["global", "alias", "declaration"] },
1316
+ "form": {
1317
+ "enum": [
1318
+ "global-property",
1319
+ "global-name",
1320
+ "guarded-global",
1321
+ "top-level-this",
1322
+ "function-return-this",
1323
+ "sloppy-this",
1324
+ "other-window",
1325
+ "singleton"
1326
+ ]
1327
+ },
1328
+ "aliasOf": { "type": "string" },
1329
+ "holds": { "type": "string" },
1330
+ "path": { "type": "string" },
1331
+ "chain": { "$ref": "#/$defs/location" },
1332
+ "declaration": {
1333
+ "type": "object",
1334
+ "required": ["kind", "generated"],
1335
+ "additionalProperties": false,
1336
+ "properties": {
1337
+ "kind": { "enum": ["var", "function", "block-function", "let", "const", "class"] },
1338
+ "generated": { "$ref": "#/$defs/location" }
1339
+ }
1340
+ },
1341
+ "realm": { "$ref": "#/$defs/realm" },
1342
+ "realmInstance": { "$ref": "#/$defs/realmInstance" }
1343
+ },
1344
+ "allOf": [
1345
+ {
1346
+ "if": { "properties": { "resolution": { "const": "alias" } } },
1347
+ "then": { "properties": { "aliasOf": true }, "required": ["aliasOf"] }
1348
+ },
1349
+ {
1350
+ "if": { "properties": { "resolution": { "const": "declaration" } } },
1351
+ "then": { "properties": { "declaration": true }, "required": ["declaration"] },
1352
+ "else": { "not": { "properties": { "declaration": true }, "required": ["declaration"] } }
1353
+ },
1354
+ {
1355
+ "if": { "properties": { "resolution": { "const": "global" } } },
1356
+ "then": { "not": { "properties": { "aliasOf": true }, "required": ["aliasOf"] } }
1357
+ },
1358
+ {
1359
+ "if": { "properties": { "form": { "const": "global-property" } } },
1360
+ "then": { "not": { "properties": { "aliasOf": true }, "required": ["aliasOf"] } },
1361
+ "else": {
1362
+ "properties": { "aliasOf": true },
1363
+ "required": ["aliasOf"],
1364
+ "not": { "properties": { "holds": true }, "required": ["holds"] }
1365
+ }
1366
+ },
1367
+ {
1368
+ "if": { "properties": { "form": { "enum": ["guarded-global", "top-level-this", "sloppy-this", "singleton"] } } },
1369
+ "then": { "properties": { "resolution": { "const": "alias" } } }
1370
+ },
1371
+ {
1372
+ "if": { "properties": { "form": { "const": "singleton" } } },
1373
+ "then": { "properties": { "path": true }, "required": ["path"] },
1374
+ "else": { "not": { "properties": { "path": true }, "required": ["path"] } }
1375
+ }
1376
+ ]
1377
+ }
1378
+ },
1379
+ {
1380
+ "if": { "properties": { "kind": { "const": "confidence-reason" } } },
1381
+ "then": {
1382
+ "description": "The evidence behind a target or mutation confidence reason the occurrence carries (§9). For `with-scope` and `direct-eval-scope`: the name whose resolution path it is on, and the sites there, in document order. For `outcome-undecidable`: the sites of what the outcome depends on and the analyzer can't see or decide (§3 Undecidable outcomes), in document order: the parts of a define's descriptor, or the object a `Reflect.set` looks its member up on. For `holder-alternatives` and `member-alternatives` (§5 Candidate sets): the branch the candidate holders or members come from, and in `alternatives` the site's other candidate targets, by name.",
1383
+ "required": ["dimension", "reason", "level"],
1384
+ "properties": {
1385
+ "dimension": { "enum": ["target", "mutation"] },
1386
+ "reason": { "type": "string" },
1387
+ "level": { "enum": ["medium", "low"] },
1388
+ "name": { "type": "string" },
1389
+ "sites": { "type": "array", "items": { "$ref": "#/$defs/location" } },
1390
+ "alternatives": { "type": "array", "items": { "type": "string" } }
1391
+ },
1392
+ "allOf": [
1393
+ {
1394
+ "if": { "properties": { "dimension": { "const": "target" } } },
1395
+ "then": {
1396
+ "properties": {
1397
+ "reason": {
1398
+ "enum": ["realm-assumed", "holder-alternatives", "member-alternatives", "direct-eval-scope", "with-scope"]
1399
+ }
1400
+ }
1401
+ },
1402
+ "else": {
1403
+ "properties": { "reason": { "enum": ["outcome-undecidable", "wildcard-outcome-mixed", "const-collision"] } }
1404
+ }
1405
+ }
1406
+ ]
1407
+ }
1408
+ },
1409
+ {
1410
+ "if": { "properties": { "kind": { "const": "note" } } },
1411
+ "then": {
1412
+ "description": "Anything else a rule requires the trace to say. `about` names the rule. `nested-code` (§2): the write is in code the native `callee` compiles from a string literal in the call at `call`, or, for `script`, in the literal text of a script element the code inserts with the call at `call`, whose names resolve in the caller's scope (a direct eval) or the global scope (`scope`). `rewritten-delete` (§3 A delete that is always rewritten): the delete of the same slot at `delete`, which the same function follows on every path with this write, gives no finding of its own. `lexical-collision` (§3 Declarations in classic scripts): another classic script in the realm, at URL `artifact`, declares the bare name `name` the write reads with a top-level `declaration` (`let`, `const` or `class`), bound at `generated` there; the name is the one written, or the one the write's holder chain starts at.",
1413
+ "required": ["about"],
1414
+ "properties": {
1415
+ "about": { "enum": ["nested-code", "rewritten-delete", "lexical-collision"] },
1416
+ "callee": { "enum": ["eval", "Function", "setTimeout", "setInterval", "script"] },
1417
+ "scope": { "enum": ["caller", "global"] },
1418
+ "call": { "$ref": "#/$defs/location" },
1419
+ "delete": { "$ref": "#/$defs/location" }
1420
+ },
1421
+ "allOf": [
1422
+ {
1423
+ "if": { "properties": { "about": { "const": "nested-code" } } },
1424
+ "then": { "properties": { "callee": true, "scope": true, "call": true }, "required": ["callee", "scope", "call"] }
1425
+ },
1426
+ {
1427
+ "if": { "properties": { "about": { "const": "rewritten-delete" } } },
1428
+ "then": { "properties": { "delete": true }, "required": ["delete"] }
1429
+ },
1430
+ {
1431
+ "if": { "properties": { "about": { "const": "lexical-collision" } } },
1432
+ "then": {
1433
+ "properties": {
1434
+ "name": { "type": "string" },
1435
+ "declaration": { "enum": ["let", "const", "class"] },
1436
+ "artifact": { "type": "string" },
1437
+ "generated": { "$ref": "#/$defs/location" }
1438
+ },
1439
+ "required": ["name", "declaration", "artifact", "generated"]
1440
+ }
1441
+ }
1442
+ ]
1443
+ }
1444
+ },
1445
+ {
1446
+ "if": { "properties": { "kind": { "const": "fold" } } },
1447
+ "then": {
1448
+ "description": "A constant or string fold (§5 Resolver capabilities 1): the `expression` at `generated` folds to the constant `value`, as `\"add\" + \"EventListener\"` folds to `\"addEventListener\"`, or to the well-known `symbol` it reads from `Symbol` (§4 Property keys), spelt as the catalog spells its members: `Symbol.iterator` folds to `@@iterator`. For a `const` read through its name, `name` is the name, and the expression is the one its value comes from: its initializer, the element or property it destructures, or its default. `expression` is printed from the syntax and cut at 120 characters.",
1449
+ "required": ["expression", "generated"],
1450
+ "properties": {
1451
+ "name": { "type": "string" },
1452
+ "expression": { "type": "string" },
1453
+ "generated": { "$ref": "#/$defs/location" }
1454
+ },
1455
+ "oneOf": [
1456
+ {
1457
+ "required": ["value"],
1458
+ "properties": {
1459
+ "value": {
1460
+ "anyOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" }]
1461
+ }
1462
+ }
1463
+ },
1464
+ {
1465
+ "required": ["symbol"],
1466
+ "properties": { "symbol": { "type": "string", "pattern": "^@@" } }
1467
+ }
1468
+ ]
1469
+ }
1470
+ },
1471
+ {
1472
+ "if": { "properties": { "kind": { "const": "guard" } } },
1473
+ "then": {
1474
+ "description": "A guard on the write's path (§7, §14): the `expression` at `generated`, printed from the syntax and cut at 120 characters; its `class`: `transparent` (the written target's own presence, a once-flag, a writability check, a test decided as a constant), `absence` (a native is missing), `broken-native` (a native judged broken rather than missing: core-js `FORCED`, a brand check, `isNativeFunction`), `config` (a config or option flag), `other-target` (the presence of a native other than the target), `unknown` (a guard the analyzer doesn't recognize, an unresolved call, `with` or direct-`eval` taint) or `undecided` (a recognized guard that can't be decided statically: sampling, `document.readyState`, `typeof global`); `tested`, the native it tests, by catalog name, when it tests one; and `result`, the reachability it gives on its own.",
1475
+ "required": ["expression", "generated", "class", "result"],
1476
+ "properties": {
1477
+ "expression": { "type": "string" },
1478
+ "generated": { "$ref": "#/$defs/location" },
1479
+ "class": { "enum": ["transparent", "absence", "broken-native", "config", "other-target", "unknown", "undecided"] },
1480
+ "tested": { "type": "string" },
1481
+ "result": { "$ref": "#/$defs/reachability" }
1482
+ },
1483
+ "allOf": [
1484
+ {
1485
+ "if": { "properties": { "class": { "const": "absence" } } },
1486
+ "then": { "required": ["tested"], "properties": { "tested": true, "result": { "const": "guarded-native-absence" } } }
1487
+ },
1488
+ {
1489
+ "if": { "properties": { "class": { "const": "transparent" } } },
1490
+ "then": { "properties": { "result": { "const": "unconditional" } } }
1491
+ },
1492
+ {
1493
+ "if": { "properties": { "class": { "const": "unknown" } } },
1494
+ "then": { "properties": { "result": { "const": "unknown" } } }
1495
+ },
1496
+ {
1497
+ "if": { "properties": { "class": { "enum": ["broken-native", "config", "other-target", "undecided"] } } },
1498
+ "then": { "properties": { "result": { "const": "conditional" } } }
1499
+ },
1500
+ {
1501
+ "if": { "properties": { "class": { "const": "other-target" } } },
1502
+ "then": { "required": ["tested"], "properties": { "tested": true } }
1503
+ }
1504
+ ]
1505
+ }
1506
+ },
1507
+ {
1508
+ "if": { "properties": { "kind": { "const": "prune" } } },
1509
+ "then": {
1510
+ "description": "Finding occurrences a statically false catalog check pruned (§7 Checking guards against the catalog, §14): `count` of them, and the guard, the test `expression` at `generated`, printed from the syntax and cut at 120 characters. It follows that guard's `guard` step on each surviving occurrence the same guard is on. With `judgement` `try-cannot-throw`, a `try` block judged unable to throw kept its `catch` arm from running (§5 Resolver capabilities 9): `count` writes in that arm were pruned, `expression` and `generated` are the `try`'s, and the step follows the guards of each surviving occurrence in that `try` block. With `judgement` `argument-literal`, a call argument object literal's field settled the test `expression` at `generated` so that an arm it guards never runs (§5 Resolver capabilities 5): `count` writes only that arm reaches were pruned, and `literal` is that object literal, printed and cut at 120 characters, with its location. The step follows the test's `guard` step on each surviving occurrence on the arm the test lets through, and the guards of each surviving occurrence whose write's values the test decided.",
1511
+ "required": ["count", "expression", "generated"],
1512
+ "properties": {
1513
+ "count": { "type": "integer", "minimum": 1 },
1514
+ "expression": { "type": "string" },
1515
+ "generated": { "$ref": "#/$defs/location" },
1516
+ "judgement": { "enum": ["try-cannot-throw", "argument-literal"] },
1517
+ "literal": {
1518
+ "type": "object",
1519
+ "additionalProperties": false,
1520
+ "required": ["expression", "generated"],
1521
+ "properties": {
1522
+ "expression": { "type": "string" },
1523
+ "generated": { "$ref": "#/$defs/location" }
1524
+ }
1525
+ }
1526
+ }
1527
+ }
1528
+ },
1529
+ {
1530
+ "if": { "properties": { "kind": { "const": "restore" } } },
1531
+ "then": {
1532
+ "description": "A proven restore in the install occurrence's chain (§3 Restores): a write at `generated` that puts back the unmutated native of the same object and member. `guard` is `identity` when it runs only while the slot still holds the code's own value, and `none` otherwise. `leavesOwnShadow` is true when it writes the native back into an own property the install created. It is evidence, never identity.",
1533
+ "required": ["generated", "guard", "leavesOwnShadow"],
1534
+ "properties": {
1535
+ "generated": { "$ref": "#/$defs/location" },
1536
+ "guard": { "enum": ["identity", "none"] },
1537
+ "leavesOwnShadow": { "type": "boolean" }
1538
+ }
1539
+ }
1540
+ },
1541
+ {
1542
+ "if": { "properties": { "kind": { "const": "alias" } } },
1543
+ "then": {
1544
+ "description": "An alias or reaching definition followed (§5 Resolver capabilities 2): the value was read through the variable `name`, from its definition that reaches the read, the `expression` at `generated`: a declarator, an assignment, an update or a loop head, as `p = XMLHttpRequest.prototype` in `var p = XMLHttpRequest.prototype`. `expression` is printed from the syntax and cut at 120 characters.",
1545
+ "required": ["name", "expression", "generated"],
1546
+ "properties": {
1547
+ "name": { "type": "string" },
1548
+ "expression": { "type": "string" },
1549
+ "generated": { "$ref": "#/$defs/location" }
1550
+ }
1551
+ }
1552
+ },
1553
+ {
1554
+ "if": { "properties": { "kind": { "const": "module-link" } } },
1555
+ "then": {
1556
+ "description": "A module-link hop the value came through (§6): `factory-table`, a require call at `generated` that runs module `module`'s factory from its table; `lazy-thunk` and `memoized-getter`, a call at `generated` of module `module`'s thunk or memoized getter, which runs it; `interop`, an interop wrapper's call at `generated` over such a call; `getter-export`, the export `export` of module `module`, which a getter export definer defines, at its getter or value. `module` is a factory table's id, or the name of the variable a module's thunk, getter or exports object is held in. `artifact` is the URL of the artifact the module is in. Module ids are build-local, so they appear here and never in identity.",
1557
+ "required": ["idiom", "module", "artifact", "generated"],
1558
+ "properties": {
1559
+ "idiom": { "enum": ["factory-table", "getter-export", "interop", "lazy-thunk", "memoized-getter"] },
1560
+ "module": { "type": "string" },
1561
+ "export": { "type": "string" },
1562
+ "artifact": { "type": "string" },
1563
+ "generated": { "$ref": "#/$defs/location" }
1564
+ }
1565
+ }
1566
+ },
1567
+ {
1568
+ "if": { "properties": { "kind": { "const": "call" } } },
1569
+ "then": {
1570
+ "description": "A summarized call (§5 Resolver capabilities 3): a value came into the function at `function` through the call at `generated`, as a parameter bound to an argument, as its `this`, or as what the function returns. `callee` is the call's callee, and `bindings` pairs each parameter with the argument the call passes it, or null when it passes none. `this` is the receiver the call dispatches through, when it passes one: the object a method is read from, or a `thisArg`. Printed expressions are cut at 120 characters.",
1571
+ "required": ["callee", "generated", "function", "bindings"],
1572
+ "properties": {
1573
+ "callee": { "type": "string" },
1574
+ "this": { "type": "string" },
1575
+ "generated": { "$ref": "#/$defs/location" },
1576
+ "function": { "$ref": "#/$defs/location" },
1577
+ "bindings": {
1578
+ "type": "array",
1579
+ "items": {
1580
+ "type": "object",
1581
+ "required": ["parameter", "argument"],
1582
+ "additionalProperties": false,
1583
+ "properties": {
1584
+ "parameter": { "type": "string" },
1585
+ "argument": { "type": ["string", "null"] }
1586
+ }
1587
+ }
1588
+ }
1589
+ }
1590
+ }
1591
+ },
1592
+ {
1593
+ "if": { "properties": { "kind": { "const": "creation-site" } } },
1594
+ "then": {
1595
+ "description": "A function object that no resolved call reaches, judged from where it was created (§5 Resolver capabilities 3, §7): the function at `function`, made at `generated`, or assumed to run with the object made there as its `this`, printed in `this`. Its creation bindings are in the `call` steps of the calls that made it. Printed expressions are cut at 120 characters.",
1596
+ "required": ["function", "generated"],
1597
+ "properties": {
1598
+ "function": { "$ref": "#/$defs/location" },
1599
+ "generated": { "$ref": "#/$defs/location" },
1600
+ "this": { "type": "string" }
1601
+ }
1602
+ }
1603
+ },
1604
+ {
1605
+ "if": { "properties": { "kind": { "const": "token-check" } } },
1606
+ "then": {
1607
+ "description": "The token check at the write's lookup point (§10): `passed` when `token` appears as a whole identifier within one line of the mapped original position `candidate`, `failed` when it doesn't, so the position is discarded, and `n/a` when the site has no token (`token` null) or the map has no source content for the candidate's source. `lookup` is the generated position looked up.",
1608
+ "required": ["result", "token", "lookup", "candidate"],
1609
+ "properties": {
1610
+ "result": { "enum": ["passed", "failed", "n/a"] },
1611
+ "token": { "type": ["string", "null"] },
1612
+ "lookup": { "$ref": "#/$defs/location" },
1613
+ "candidate": { "$ref": "#/$defs/originalLocation" }
1614
+ }
1615
+ }
1616
+ },
1617
+ {
1618
+ "if": { "properties": { "kind": { "const": "path-rule" } } },
1619
+ "then": {
1620
+ "description": "The framework path rule (§10) that named the package of an escaped source: the rule's catalog id `rule`, the `package` it named, and the raw `source` it matched.",
1621
+ "required": ["rule", "package", "source"],
1622
+ "properties": {
1623
+ "rule": { "type": "string" },
1624
+ "package": { "type": "string" },
1625
+ "source": { "type": "string" }
1626
+ }
1627
+ }
1628
+ },
1629
+ {
1630
+ "if": { "properties": { "kind": { "const": "enumeration" } } },
1631
+ "then": {
1632
+ "description": "One of two shapes. A member sweep the catalog expanded (§5 Resolver capabilities 9): the enumeration `expression` at `generated` (the call, or a `for…in` loop's object), printed from the syntax and cut at 120 characters, swept the native `holder` by `enumeration` and gave the catalog `member`. `filters` are the filters the key went through, in order: `kept` when the filter keeps the member, `undecided` when the analyzer can't tell, which makes reachability `conditional`. Or a configurable wildcard prefix (§5 Pattern wildcards): the key `expression` at `generated`, written on `holder`, starts with a prefix whose other alternatives the analyzer can't resolve, which give nothing; `prefix` is its default, the literal alternative the wildcard comes from.",
1633
+ "required": ["expression", "generated", "holder"],
1634
+ "properties": {
1635
+ "expression": { "type": "string" },
1636
+ "generated": { "$ref": "#/$defs/location" },
1637
+ "holder": { "type": "string" }
1638
+ },
1639
+ "oneOf": [
1640
+ {
1641
+ "required": ["enumeration", "member", "filters"],
1642
+ "properties": {
1643
+ "enumeration": {
1644
+ "enum": [
1645
+ "for-in",
1646
+ "Object.keys",
1647
+ "Object.getOwnPropertyNames",
1648
+ "Object.entries",
1649
+ "Object.getOwnPropertyDescriptors",
1650
+ "Reflect.ownKeys",
1651
+ "Object.getOwnPropertySymbols"
1652
+ ]
1653
+ },
1654
+ "member": { "type": "string" },
1655
+ "filters": {
1656
+ "type": "array",
1657
+ "items": {
1658
+ "type": "object",
1659
+ "required": ["expression", "generated", "result"],
1660
+ "additionalProperties": false,
1661
+ "properties": {
1662
+ "expression": { "type": "string" },
1663
+ "generated": { "$ref": "#/$defs/location" },
1664
+ "result": { "enum": ["kept", "undecided"] }
1665
+ }
1666
+ }
1667
+ }
1668
+ }
1669
+ },
1670
+ {
1671
+ "required": ["prefix", "configurable"],
1672
+ "properties": { "prefix": { "type": "string", "minLength": 1 }, "configurable": { "const": true } }
1673
+ }
1674
+ ]
1675
+ }
1676
+ },
1677
+ {
1678
+ "if": { "properties": { "kind": { "const": "catalog-holder" } } },
1679
+ "then": {
1680
+ "description": "A holder the unmutated catalog chose (§4), by the `expression` at `generated`, printed from the syntax and cut at 120 characters. It is one of: a prototype step, where `Object.getPrototypeOf(h)` (or `h.__proto__`) of the native holder `prototypeOf` is `holder`, its prototype in the unmutated catalog, as `Object.getPrototypeOf(console)` is `console.[[Prototype]]`; an own-property test, whether the native holder `tested` `owns` the catalog `member`, which chose the holder a runtime choice takes (with no `member`, the key didn't fold and `tested` owns only the structural `constructor`, `@@toStringTag` and `prototype`, so it owns none that counts); or a prototype walk to the first owner, the holders `walk` visits from its start value, in order, and `holder`, the first that owns `member` (with no `member`, the key didn't fold and `holder` is one holder that may own it).",
1681
+ "required": ["expression", "generated"],
1682
+ "properties": {
1683
+ "expression": { "type": "string" },
1684
+ "generated": { "$ref": "#/$defs/location" }
1685
+ },
1686
+ "oneOf": [
1687
+ {
1688
+ "required": ["prototypeOf", "holder"],
1689
+ "properties": { "prototypeOf": { "type": "string" }, "holder": { "type": "string" } }
1690
+ },
1691
+ {
1692
+ "required": ["tested", "owns"],
1693
+ "properties": { "tested": { "type": "string" }, "member": { "type": "string" }, "owns": { "type": "boolean" } }
1694
+ },
1695
+ {
1696
+ "required": ["walk", "holder"],
1697
+ "properties": {
1698
+ "walk": { "type": "array", "minItems": 1, "items": { "type": "string" } },
1699
+ "member": { "type": "string" },
1700
+ "holder": { "type": "string" }
1701
+ }
1702
+ }
1703
+ ]
1704
+ }
1705
+ },
1706
+ {
1707
+ "if": { "properties": { "kind": { "const": "outcome" } } },
1708
+ "then": {
1709
+ "description": "The outcome table's decision on an ineffective write (§3): its `reason`, whether it `throws`, and `mayChangeNothing`, which says that on a value the analyzer can't see the write could instead change nothing (§3 No-op or ineffective).",
1710
+ "required": ["result", "reason", "throws", "mayChangeNothing"],
1711
+ "properties": {
1712
+ "result": { "const": "ineffective" },
1713
+ "reason": { "$ref": "#/$defs/ineffectiveWrite/properties/reason" },
1714
+ "throws": { "$ref": "#/$defs/ineffectiveOccurrence/properties/throws" },
1715
+ "mayChangeNothing": { "type": "boolean" }
1716
+ }
1717
+ }
1718
+ }
1719
+ ]
1720
+ },
1721
+ "artifact": {
1722
+ "type": "object",
1723
+ "required": ["url", "path", "hash", "origin", "discovery", "sourceType", "realm", "realmBasis", "parent", "sourceMap", "retrieval", "moduleLinking"],
1724
+ "additionalProperties": false,
1725
+ "properties": {
1726
+ "url": { "type": "string" },
1727
+ "path": { "type": ["string", "null"], "description": "Build-relative POSIX path of a local artifact; null otherwise." },
1728
+ "hash": {
1729
+ "description": "The content hash of the artifact's bytes; null when they were never read, or were fetched but withheld because they don't match their integrity value (`retrieval.status` `sri-mismatch`, §17 Integrity).",
1730
+ "type": ["string", "null"],
1731
+ "pattern": "^sha256:[0-9a-f]{64}$"
1732
+ },
1733
+ "origin": { "$ref": "#/$defs/origin" },
1734
+ "discovery": {
1735
+ "description": "How it was found (§2): by following a reference, or only by the build-directory sweep (`sweep`).",
1736
+ "enum": ["reference", "injected", "sweep"]
1737
+ },
1738
+ "sourceType": { "enum": ["script", "module"] },
1739
+ "realm": {
1740
+ "description": "The realm it runs in, from how it was referenced (§2 Realm). A URL referenced in two realms is an artifact in each, and a URL a page runs both as a classic script and as a module is an artifact each way.",
1741
+ "$ref": "#/$defs/realm"
1742
+ },
1743
+ "realmBasis": {
1744
+ "description": "How its realm is known (§2 Realm): from how it was referenced, or assumed to be `window` because only the sweep found it, or only a `<link rel=preload as=script>` names it, or only the imports of code whose realm is assumed name it (§2 Files that don't run as referenced).",
1745
+ "enum": ["reference", "assumed"]
1746
+ },
1747
+ "parent": {
1748
+ "description": "The URL of what first references it in its realm (§2 parent or importer): the entry document whose element names it, or the script or module that imports it, creates its worker or loads it with `importScripts`. Null for an artifact only the sweep found.",
1749
+ "type": ["string", "null"]
1750
+ },
1751
+ "sourceMap": {
1752
+ "description": "Its source map (§2 Source maps): the method that paired the first candidate that verified, and the map's path: build-relative, or for a source-map directory's map, the directory as declared joined with its path there (null for a `data:` URL or a fetched map). Without one, `method` is `none`, and `status` says whether every candidate failed verification (`stale`, with the first one's path) or none was found (`none`).",
1753
+ "type": "object",
1754
+ "required": ["method", "path", "status"],
1755
+ "additionalProperties": false,
1756
+ "properties": {
1757
+ "method": {
1758
+ "enum": ["header", "annotation", "sidecar", "debug-id", "external-debug-id", "external-annotation", "external-sidecar", "none"]
1759
+ },
1760
+ "path": { "type": ["string", "null"] },
1761
+ "status": { "enum": ["verified", "stale", "none"] }
1762
+ },
1763
+ "allOf": [
1764
+ {
1765
+ "if": { "properties": { "status": { "const": "verified" } } },
1766
+ "then": { "properties": { "method": { "not": { "const": "none" } } } },
1767
+ "else": { "properties": { "method": { "const": "none" } } }
1768
+ },
1769
+ {
1770
+ "if": { "properties": { "status": { "const": "none" } } },
1771
+ "then": { "properties": { "path": { "type": "null" } } }
1772
+ }
1773
+ ]
1774
+ },
1775
+ "moduleLinking": {
1776
+ "description": "The artifact's module linking (§6): the module-linking idioms it uses (`chunk-loader`, `factory-table`, `getter-export`, `interop`, `lazy-thunk`, `memoized-getter`), in code-unit order, as a best-effort report that is never identity; how many modules its factory tables, chunk-registry pushes, lazy module thunks and memoized getters hold; how many broken links it has (a require call whose id isn't a constant or names no factory in the table), each counted whether or not it raised `unlinked-module-call`; and how many link groups it was analyzed in, 0 when it wasn't analyzed.",
1777
+ "type": "object",
1778
+ "required": ["idioms", "modules", "unlinked", "linkGroups"],
1779
+ "additionalProperties": false,
1780
+ "properties": {
1781
+ "idioms": { "type": "array", "items": { "enum": ["chunk-loader", "factory-table", "getter-export", "interop", "lazy-thunk", "memoized-getter"] } },
1782
+ "modules": { "type": "integer", "minimum": 0 },
1783
+ "unlinked": { "type": "integer", "minimum": 0 },
1784
+ "linkGroups": { "type": "integer", "minimum": 0 }
1785
+ }
1786
+ },
1787
+ "retrieval": {
1788
+ "description": "How the artifact's bytes were retrieved (§17 What is recorded). Wall-clock facts of a fetch are in run.retrievals.",
1789
+ "type": "object",
1790
+ "required": ["status", "requestedUrl", "finalUrl", "contentType", "sri"],
1791
+ "additionalProperties": false,
1792
+ "properties": {
1793
+ "status": {
1794
+ "description": "Whether the artifact's bytes were read (`ok`), or why not: a local file can't be read (`unreadable`), a remote one isn't fetched offline (`offline-skipped`), the safety floor refused its fetch (`remote-refused`, §17), its fetch failed (`fetch-failed`), or the fetched bytes don't match their integrity value (`sri-mismatch`), so they are not analyzed.",
1795
+ "enum": ["ok", "unreadable", "offline-skipped", "remote-refused", "fetch-failed", "sri-mismatch"]
1796
+ },
1797
+ "requestedUrl": {
1798
+ "description": "The URL the reference requested, which the artifact's URL, origin and attribution key come from: for a `data:` URL, that URL, whose code is `inline` (§2 Other script URLs). Code a redirected script references is requested against the script's final URL, but its artifact's URL, origin and attribution key come from the URL resolved against the script's own requested URL (§11, §17). Null for an inline script, which is never requested.",
1799
+ "type": ["string", "null"]
1800
+ },
1801
+ "finalUrl": {
1802
+ "description": "The URL the retrieval ended at, after any redirects. A build file's or a `data:` URL's is the requested URL. Null when nothing answered: offline, a fetch that got no response, and an inline script.",
1803
+ "type": ["string", "null"]
1804
+ },
1805
+ "contentType": {
1806
+ "description": "The Content-Type of the response, as served, or the MIME type of a `data:` URL (`text/plain;charset=US-ASCII` when it names none that parses). Null for a build file, an inline script, and a fetch with no response or no such header.",
1807
+ "type": ["string", "null"]
1808
+ },
1809
+ "sri": {
1810
+ "description": "The Subresource Integrity check of the fetched bytes (§17 Integrity). `none` when no integrity value was checked: the reference carries none (or none in a supported algorithm), the bytes are a build file's or an inline script's, which are never fetched, or the check never ran: the script was skipped offline, its fetch failed, or the safety floor refused it before the check (every refusal but the one after it, below; §17 Content types). Otherwise the check, which a `remote-refused` artifact carries only when its bytes matched and were then refused for lacking the JavaScript MIME type its destination needs: whether the bytes `match`, `expected`, the integrity value's digests in the strongest algorithm it names, which is the one used, and `actual`, the bytes' digest in that algorithm, each as `<algorithm>-<base64>`.",
1811
+ "oneOf": [
1812
+ { "const": "none" },
1813
+ {
1814
+ "type": "object",
1815
+ "required": ["result", "expected", "actual"],
1816
+ "additionalProperties": false,
1817
+ "properties": {
1818
+ "result": { "enum": ["match", "mismatch"] },
1819
+ "expected": {
1820
+ "type": "array",
1821
+ "minItems": 1,
1822
+ "items": { "$ref": "#/$defs/sriDigest" }
1823
+ },
1824
+ "actual": { "$ref": "#/$defs/sriDigest" }
1825
+ }
1826
+ }
1827
+ ]
1828
+ }
1829
+ }
1830
+ }
1831
+ }
1832
+ },
1833
+ "count": { "type": "integer", "minimum": 0 },
1834
+ "sriDigest": {
1835
+ "description": "A digest as Subresource Integrity writes it: the algorithm, `-`, and the base64 value.",
1836
+ "type": "string",
1837
+ "pattern": "^sha(256|384|512)-"
1838
+ },
1839
+ "versionSkew": {
1840
+ "description": "The baseline was written by another version (§4 Version skew): each version the baseline file was written with, and the scan's. An older baseline scans normally, and a delta without explainedBy may come from analyzer changes. A newer one (a stale install) scans with a warning and no explainedBy, and baseline update refuses to rewrite it without --allow-downgrade. An older formatVersion or fingerprint scheme has been migrated in memory, and baseline update rewrites it.",
1841
+ "type": "object",
1842
+ "required": ["kind", "newer", "formatVersion", "fingerprintScheme", "catalogVersion", "monkeypatchlistVersion"],
1843
+ "additionalProperties": false,
1844
+ "properties": {
1845
+ "kind": { "const": "version-skew" },
1846
+ "newer": {
1847
+ "description": "The side written by the newer version: `baseline` when any of the baseline's versions is newer than the scan's, otherwise `scan`.",
1848
+ "enum": ["baseline", "scan"]
1849
+ },
1850
+ "formatVersion": { "$ref": "#/$defs/versionPair" },
1851
+ "fingerprintScheme": { "$ref": "#/$defs/versionPair" },
1852
+ "catalogVersion": { "$ref": "#/$defs/versionPair" },
1853
+ "monkeypatchlistVersion": {
1854
+ "type": "object",
1855
+ "required": ["baseline", "scan"],
1856
+ "additionalProperties": false,
1857
+ "properties": { "baseline": { "type": "string" }, "scan": { "type": "string" } }
1858
+ }
1859
+ }
1860
+ },
1861
+ "versionPair": {
1862
+ "type": "object",
1863
+ "required": ["baseline", "scan"],
1864
+ "additionalProperties": false,
1865
+ "properties": { "baseline": { "type": "integer" }, "scan": { "type": "integer" } }
1866
+ },
1867
+ "limitation": {
1868
+ "description": "A limitation record (§13). `artifact` holds what is known of it: its URL or path, and its hash.",
1869
+ "type": "object",
1870
+ "required": ["kind", "artifact", "detail"],
1871
+ "additionalProperties": false,
1872
+ "properties": {
1873
+ "kind": {
1874
+ "enum": [
1875
+ "parse-failure",
1876
+ "unreadable",
1877
+ "source-maps-unpaired",
1878
+ "fetch-failed",
1879
+ "sri-mismatch",
1880
+ "remote-refused",
1881
+ "offline-skipped",
1882
+ "dynamic-code",
1883
+ "unresolved-reference",
1884
+ "realm-uncertain",
1885
+ "unresolved-holder",
1886
+ "unlinked-module-call",
1887
+ "analysis-budget"
1888
+ ]
1889
+ },
1890
+ "artifact": {
1891
+ "type": "object",
1892
+ "minProperties": 1,
1893
+ "additionalProperties": false,
1894
+ "properties": {
1895
+ "url": { "type": "string" },
1896
+ "path": { "type": "string" },
1897
+ "hash": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" }
1898
+ }
1899
+ },
1900
+ "location": { "$ref": "#/$defs/location" },
1901
+ "detail": { "type": "string" }
1902
+ }
1903
+ }
1904
+ }
1905
+ }