changedOutput schema / oneOf
Previous value: -[
- {
- "additionalProperties": false,
- "properties": {
- "coverage": {
- "anyOf": [
- {
- "additionalProperties": false,
- "properties": {
- "batch_size": {
- "description": "The most purls one request carries (the API's cap per request).",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "batches": {
- "description": "Requests the distinct purls make, at batch_size each.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "batches_sent": {
- "description": "Of those, the ones the API answered.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "components_in_document": {
- "anyOf": [
- {
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "description": "Components (CycloneDX) or packages (SPDX) in the document; null for a purl list."
- },
- "distinct_purls": {
- "description": "Distinct purls to check: sent plus not_sent.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "duplicates_removed": {
- "description": "Purls that appeared more than once and were sent once.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "input": {
- "description": "What was passed: a purl list, a CycloneDX JSON document or an SPDX JSON document.",
- "enum": [
- "purls",
- "cyclonedx",
- "spdx"
- ],
- "type": "string"
- },
- "not_assessed": {
- "anyOf": [
- {
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "description": "Of those sent, the components with no verdict, as the answer counts them."
- },
- "not_sent": {
- "description": "Distinct purls not sent, listed in data.not_sent_purls: not checked, and not clean.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "not_sent_reason": {
- "anyOf": [
- {
- "enum": [
- "time_budget",
- "rate_limited",
- "request_failed"
- ],
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "description": "Why not_sent is above 0: time_budget (the call's 50 s budget ran out, or waiting out the API's Retry-After would pass it), rate_limited (a 429 without Retry-After, or a 429 after 10 waits), request_failed (a batch after the first failed; the note quotes how). null when every purl was sent."
- },
- "partial": {
- "description": "true when not every purl was sent (not_sent above 0) or any batch's summary.partial was true (its time budget ran out first); otherwise the answer's summary.partial.",
- "type": [
- "boolean",
- "null"
- ]
- },
- "rate_limit_waits": {
- "description": "How many times the API answered 429 and the tool waited its Retry-After before sending the batch again.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "sent": {
- "description": "Distinct purls sent and answered.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "waited_ms": {
- "description": "Milliseconds spent in those waits.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "with_purl": {
- "description": "Of those, the ones carrying a purl.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "without_purl": {
- "description": "The ones without a purl: not checked, and not clean.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- }
- },
- "required": [
- "input",
- "components_in_document",
- "with_purl",
- "without_purl",
- "duplicates_removed",
- "distinct_purls",
- "batch_size",
- "batches",
- "batches_sent",
- "sent",
- "not_sent",
- "not_sent_reason",
- "rate_limit_waits",
- "waited_ms",
- "not_assessed",
- "partial"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "description": "What the answer covers; null where the answer says nothing about it."
- },
- "data": {
- "additionalProperties": {},
- "properties": {
- "answered_at": {
- "type": [
- "string",
- "null"
- ]
- },
- "components": {
- "type": [
- "number",
- "null"
- ]
- },
- "match_layer": {
- "type": [
- "string",
- "null"
- ]
- },
- "not_sent_purls": {
- "anyOf": [
- {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- {
- "type": "null"
- }
- ],
- "description": "The distinct purls not sent (coverage.not_sent_reason says why): not checked, and not clean. Present only when some were not sent."
- },
- "results": {
- "items": {
- "additionalProperties": {},
- "properties": {
- "advisories_considered": {
- "type": [
- "number",
- "null"
- ]
- },
- "assessed": {
- "description": "Whether the matcher produced a verdict for this component. false is never clean.",
- "type": [
- "boolean",
- "null"
- ]
- },
- "candidates_capped": {
- "type": [
- "boolean",
- "null"
- ]
- },
- "capped": {
- "type": [
- "boolean",
- "null"
- ]
- },
- "code": {
- "type": [
- "string",
- "null"
- ]
- },
- "count": {
- "type": [
- "number",
- "null"
- ]
- },
- "cve_ids": {
- "anyOf": [
- {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- {
- "type": "null"
- }
- ]
- },
- "ecosystem": {
- "type": [
- "string",
- "null"
- ]
- },
- "error": {
- "type": [
- "string",
- "null"
- ]
- },
- "index": {
- "type": [
- "number",
- "null"
- ]
- },
- "input_kind": {
- "type": [
- "string",
- "null"
- ]
- },
- "matches": {
- "anyOf": [
- {
- "items": {
- "additionalProperties": {},
- "properties": {
- "cve_id": {
- "type": [
- "string",
- "null"
- ]
- }
- },
- "type": "object"
- },
- "type": "array"
- },
- {
- "type": "null"
- }
- ]
- },
- "not_affected_count": {
- "type": [
- "number",
- "null"
- ]
- },
- "not_assessed_reason": {
- "description": "Why assessed is false: package_not_in_advisory_corpus, no_decidable_advisory, advisory_lookup_failed, candidate_window_truncated, time_budget, distro_release_unknown, purl_type_unsupported, version_missing or invalid_component.",
- "type": [
- "string",
- "null"
- ]
- },
- "package": {
- "type": [
- "string",
- "null"
- ]
- },
- "purl": {
- "type": [
- "string",
- "null"
- ]
- },
- "undetermined": {
- "anyOf": [
- {
- "items": {
- "additionalProperties": {},
- "properties": {
- "cve_id": {
- "type": [
- "string",
- "null"
- ]
- }
- },
- "type": "object"
- },
- "type": "array"
- },
- {
- "type": "null"
- }
- ]
- },
- "undetermined_count": {
- "type": [
- "number",
- "null"
- ]
- },
- "verdict": {
- "description": "affected (count > 0); not_affected (assessed, no match, nothing undetermined: the only clean verdict); undetermined (advisories name the package, at least one could not be decided, none matched: not clean); not_assessed (no verdict: not clean).",
- "type": [
- "string",
- "null"
- ]
- },
- "version": {
- "type": [
- "string",
- "null"
- ]
- }
- },
- "type": "object"
- },
- "type": "array"
- },
- "summary": {
- "additionalProperties": {},
- "properties": {
- "affected": {
- "type": [
- "number",
- "null"
- ]
- },
- "components": {
- "type": [
- "number",
- "null"
- ]
- },
- "corpus_cache_max_age_ms": {
- "type": [
- "number",
- "null"
- ]
- },
- "elapsed_ms": {
- "type": [
- "number",
- "null"
- ]
- },
- "lookups": {
- "type": [
- "number",
- "null"
- ]
- },
- "not_affected": {
- "description": "Components with a decided, clean verdict.",
- "type": [
- "number",
- "null"
- ]
- },
- "not_assessed": {
- "description": "Components with no verdict: not clean.",
- "type": [
- "number",
- "null"
- ]
- },
- "not_assessed_by_reason": {
- "anyOf": [
- {
- "additionalProperties": {},
- "properties": {
- "advisory_lookup_failed": {
- "type": "number"
- },
- "candidate_window_truncated": {
- "type": "number"
- },
- "distro_release_unknown": {
- "description": "deb, apk or rpm purls without a distro qualifier naming the release, which EchelonGraph does not guess.",
- "type": "number"
- },
- "invalid_component": {
- "type": "number"
- },
- "no_decidable_advisory": {
- "type": "number"
- },
- "package_not_in_advisory_corpus": {
- "type": "number"
- },
- "purl_type_unsupported": {
- "type": "number"
- },
- "time_budget": {
- "description": "Components the batch's time budget ran out before: not clean; check them again.",
- "type": "number"
- },
- "version_missing": {
- "type": "number"
- }
- },
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "description": "The not_assessed components, counted by not_assessed_reason."
- },
- "partial": {
- "description": "true when the time budget ran out before every component was looked up.",
- "type": [
- "boolean",
- "null"
- ]
- },
- "time_budget_ms": {
- "type": [
- "number",
- "null"
- ]
- },
- "undetermined": {
- "description": "Components whose advisories could not all be decided and none matched: not clean.",
- "type": [
- "number",
- "null"
- ]
- }
- },
- "type": "object"
- }
- },
- "type": "object"
- },
- "freshness": {
- "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
- "type": "null"
- },
- "measured_at": {
- "anyOf": [
- {
- "description": "An RFC 3339 instant.",
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
- },
- "method": {
- "description": "How the numbers were produced.",
- "type": "string"
- },
- "notes": {
- "description": "Caveats, one sentence each.",
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "state": {
- "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
- "enum": [
- "measured",
- "not_assessed"
- ],
- "type": "string"
- }
- },
- "required": [
- "state",
- "measured_at",
- "method",
- "coverage",
- "freshness",
- "notes",
- "data"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "coverage": {
- "anyOf": [
- {
- "additionalProperties": false,
- "properties": {
- "batch_size": {
- "description": "The most purls one request carries (the API's cap per request).",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "batches": {
- "description": "Requests the distinct purls make, at batch_size each.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "batches_sent": {
- "description": "Of those, the ones the API answered.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "components_in_document": {
- "anyOf": [
- {
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "description": "Components (CycloneDX) or packages (SPDX) in the document; null for a purl list."
- },
- "distinct_purls": {
- "description": "Distinct purls to check: sent plus not_sent.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "duplicates_removed": {
- "description": "Purls that appeared more than once and were sent once.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "input": {
- "description": "What was passed: a purl list, a CycloneDX JSON document or an SPDX JSON document.",
- "enum": [
- "purls",
- "cyclonedx",
- "spdx"
- ],
- "type": "string"
- },
- "not_assessed": {
- "anyOf": [
- {
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "description": "Of those sent, the components with no verdict, as the answer counts them."
- },
- "not_sent": {
- "description": "Distinct purls not sent, listed in data.not_sent_purls: not checked, and not clean.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "not_sent_reason": {
- "anyOf": [
- {
- "enum": [
- "time_budget",
- "rate_limited",
- "request_failed"
- ],
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "description": "Why not_sent is above 0: time_budget (the call's 50 s budget ran out, or waiting out the API's Retry-After would pass it), rate_limited (a 429 without Retry-After, or a 429 after 10 waits), request_failed (a batch after the first failed; the note quotes how). null when every purl was sent."
- },
- "partial": {
- "description": "true when not every purl was sent (not_sent above 0) or any batch's summary.partial was true (its time budget ran out first); otherwise the answer's summary.partial.",
- "type": [
- "boolean",
- "null"
- ]
- },
- "rate_limit_waits": {
- "description": "How many times the API answered 429 and the tool waited its Retry-After before sending the batch again.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "sent": {
- "description": "Distinct purls sent and answered.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "waited_ms": {
- "description": "Milliseconds spent in those waits.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "with_purl": {
- "description": "Of those, the ones carrying a purl.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- "without_purl": {
- "description": "The ones without a purl: not checked, and not clean.",
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- }
- },
- "required": [
- "input",
- "components_in_document",
- "with_purl",
- "without_purl",
- "duplicates_removed",
- "distinct_purls",
- "batch_size",
- "batches",
- "batches_sent",
- "sent",
- "not_sent",
- "not_sent_reason",
- "rate_limit_waits",
- "waited_ms",
- "not_assessed",
- "partial"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ]
- },
- "error": {
- "additionalProperties": false,
- "properties": {
- "kind": {
- "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
- "enum": [
- "network",
- "timeout",
- "http",
- "not_json",
- "not_object",
- "invalid_input",
- "internal",
- "unexpected_shape",
- "radars"
- ],
- "type": "string"
- },
- "message": {
- "description": "The cause: the API's own message, or what went wrong.",
- "type": "string"
- },
- "path": {
- "description": "The API path requested, when a request was made.",
- "type": [
- "string",
- "null"
- ]
- },
- "status": {
- "anyOf": [
- {
- "maximum": 9007199254740991,
- "minimum": -9007199254740991,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "description": "The HTTP status, when the API answered one."
- }
- },
- "required": [
- "kind",
- "path",
- "status",
- "message"
- ],
- "type": "object"
- },
- "freshness": {
- "type": "null"
- },
- "measured_at": {
- "type": "null"
- },
- "method": {
- "type": "null"
- },
- "notes": {
- "description": "Caveats, one sentence each.",
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "state": {
- "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
- "enum": [
- "failed",
- "invalid_input"
- ],
- "type": "string"
- }
- },
- "required": [
- "state",
- "measured_at",
- "method",
- "coverage",
- "freshness",
- "notes",
- "error"
- ],
- "type": "object"
- }
-]New value: +[
+ {
+ "additionalProperties": false,
+ "properties": {
+ "coverage": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "properties": {
+ "batch_size": {
+ "description": "The most purls one request carries (the API's cap per request).",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "batches": {
+ "description": "Requests the distinct purls make, at batch_size each.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "batches_sent": {
+ "description": "Of those, the ones the API answered.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "components_in_document": {
+ "anyOf": [
+ {
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Components (CycloneDX) or packages (SPDX) in the document; null for a purl list."
+ },
+ "distinct_purls": {
+ "description": "Distinct purls to check: sent plus not_sent.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "duplicates_removed": {
+ "description": "Purls that appeared more than once and were sent once.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "input": {
+ "description": "What was passed: a purl list, a CycloneDX JSON document or an SPDX JSON document.",
+ "enum": [
+ "purls",
+ "cyclonedx",
+ "spdx"
+ ],
+ "type": "string"
+ },
+ "not_assessed": {
+ "anyOf": [
+ {
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Of those sent, the components with no verdict, as the answer counts them."
+ },
+ "not_sent": {
+ "description": "Distinct purls not sent, listed in data.not_sent_purls: not checked, and not clean.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "not_sent_reason": {
+ "anyOf": [
+ {
+ "enum": [
+ "time_budget",
+ "rate_limited",
+ "request_failed"
+ ],
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Why not_sent is above 0: time_budget (the call's 50 s budget ran out, before a batch or while one was unanswered, which is then cut off; or waiting out the API's Retry-After would pass it), rate_limited (a 429 without Retry-After, or a 429 after 10 waits), request_failed (a batch after the first failed; the note quotes how). null when every purl was sent."
+ },
+ "partial": {
+ "description": "true when not every purl was sent (not_sent above 0) or any batch's summary.partial was true (its time budget ran out first); otherwise the answer's summary.partial.",
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "rate_limit_waits": {
+ "description": "How many times the API answered 429 and the tool waited its Retry-After before sending the batch again.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "sent": {
+ "description": "Distinct purls sent and answered.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "waited_ms": {
+ "description": "Milliseconds spent in those waits.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "with_purl": {
+ "description": "Of those, the ones carrying a purl.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "without_purl": {
+ "description": "The ones without a purl: not checked, and not clean.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ }
+ },
+ "required": [
+ "input",
+ "components_in_document",
+ "with_purl",
+ "without_purl",
+ "duplicates_removed",
+ "distinct_purls",
+ "batch_size",
+ "batches",
+ "batches_sent",
+ "sent",
+ "not_sent",
+ "not_sent_reason",
+ "rate_limit_waits",
+ "waited_ms",
+ "not_assessed",
+ "partial"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "What the answer covers; null where the answer says nothing about it."
+ },
+ "data": {
+ "additionalProperties": {},
+ "properties": {
+ "answered_at": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "components": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "match_layer": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "not_sent_purls": {
+ "anyOf": [
+ {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The distinct purls not sent (coverage.not_sent_reason says why): not checked, and not clean. Present only when some were not sent."
+ },
+ "results": {
+ "items": {
+ "additionalProperties": {},
+ "properties": {
+ "advisories_considered": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "assessed": {
+ "description": "Whether the matcher produced a verdict for this component. false is never clean.",
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "candidates_capped": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "capped": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "code": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "count": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "cve_ids": {
+ "anyOf": [
+ {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "ecosystem": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "error": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "index": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "input_kind": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "matches": {
+ "anyOf": [
+ {
+ "items": {
+ "additionalProperties": {},
+ "properties": {
+ "cve_id": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "type": "object"
+ },
+ "type": "array"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "not_affected_count": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "not_assessed_reason": {
+ "description": "Why assessed is false: package_not_in_advisory_corpus, no_decidable_advisory, advisory_lookup_failed, candidate_window_truncated, time_budget, distro_release_unknown, purl_type_unsupported, version_missing or invalid_component.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "package": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "purl": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "undetermined": {
+ "anyOf": [
+ {
+ "items": {
+ "additionalProperties": {},
+ "properties": {
+ "cve_id": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "type": "object"
+ },
+ "type": "array"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "undetermined_count": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "verdict": {
+ "description": "affected (count > 0); not_affected (assessed, no match, nothing undetermined: the only clean verdict); undetermined (advisories name the package, at least one could not be decided, none matched: not clean); not_assessed (no verdict: not clean).",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "version": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "summary": {
+ "additionalProperties": {},
+ "properties": {
+ "affected": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "components": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "corpus_cache_max_age_ms": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "elapsed_ms": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "lookups": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "not_affected": {
+ "description": "Components with a decided, clean verdict.",
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "not_assessed": {
+ "description": "Components with no verdict: not clean.",
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "not_assessed_by_reason": {
+ "anyOf": [
+ {
+ "additionalProperties": {},
+ "properties": {
+ "advisory_lookup_failed": {
+ "type": "number"
+ },
+ "candidate_window_truncated": {
+ "type": "number"
+ },
+ "distro_release_unknown": {
+ "description": "deb, apk or rpm purls without a distro qualifier naming the release, which EchelonGraph does not guess.",
+ "type": "number"
+ },
+ "invalid_component": {
+ "type": "number"
+ },
+ "no_decidable_advisory": {
+ "type": "number"
+ },
+ "package_not_in_advisory_corpus": {
+ "type": "number"
+ },
+ "purl_type_unsupported": {
+ "type": "number"
+ },
+ "time_budget": {
+ "description": "Components the batch's time budget ran out before: not clean; check them again.",
+ "type": "number"
+ },
+ "version_missing": {
+ "type": "number"
+ }
+ },
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The not_assessed components, counted by not_assessed_reason."
+ },
+ "partial": {
+ "description": "true when the time budget ran out before every component was looked up.",
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "time_budget_ms": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "undetermined": {
+ "description": "Components whose advisories could not all be decided and none matched: not clean.",
+ "type": [
+ "number",
+ "null"
+ ]
+ }
+ },
+ "type": "object"
+ }
+ },
+ "type": "object"
+ },
+ "freshness": {
+ "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
+ "type": "null"
+ },
+ "measured_at": {
+ "anyOf": [
+ {
+ "description": "An RFC 3339 instant.",
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
+ },
+ "method": {
+ "description": "How the numbers were produced.",
+ "type": "string"
+ },
+ "notes": {
+ "description": "Caveats, one sentence each.",
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "state": {
+ "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
+ "enum": [
+ "measured",
+ "not_assessed"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "state",
+ "measured_at",
+ "method",
+ "coverage",
+ "freshness",
+ "notes",
+ "data"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "coverage": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "properties": {
+ "batch_size": {
+ "description": "The most purls one request carries (the API's cap per request).",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "batches": {
+ "description": "Requests the distinct purls make, at batch_size each.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "batches_sent": {
+ "description": "Of those, the ones the API answered.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "components_in_document": {
+ "anyOf": [
+ {
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Components (CycloneDX) or packages (SPDX) in the document; null for a purl list."
+ },
+ "distinct_purls": {
+ "description": "Distinct purls to check: sent plus not_sent.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "duplicates_removed": {
+ "description": "Purls that appeared more than once and were sent once.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "input": {
+ "description": "What was passed: a purl list, a CycloneDX JSON document or an SPDX JSON document.",
+ "enum": [
+ "purls",
+ "cyclonedx",
+ "spdx"
+ ],
+ "type": "string"
+ },
+ "not_assessed": {
+ "anyOf": [
+ {
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Of those sent, the components with no verdict, as the answer counts them."
+ },
+ "not_sent": {
+ "description": "Distinct purls not sent, listed in data.not_sent_purls: not checked, and not clean.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "not_sent_reason": {
+ "anyOf": [
+ {
+ "enum": [
+ "time_budget",
+ "rate_limited",
+ "request_failed"
+ ],
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Why not_sent is above 0: time_budget (the call's 50 s budget ran out, before a batch or while one was unanswered, which is then cut off; or waiting out the API's Retry-After would pass it), rate_limited (a 429 without Retry-After, or a 429 after 10 waits), request_failed (a batch after the first failed; the note quotes how). null when every purl was sent."
+ },
+ "partial": {
+ "description": "true when not every purl was sent (not_sent above 0) or any batch's summary.partial was true (its time budget ran out first); otherwise the answer's summary.partial.",
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "rate_limit_waits": {
+ "description": "How many times the API answered 429 and the tool waited its Retry-After before sending the batch again.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "sent": {
+ "description": "Distinct purls sent and answered.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "waited_ms": {
+ "description": "Milliseconds spent in those waits.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "with_purl": {
+ "description": "Of those, the ones carrying a purl.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ "without_purl": {
+ "description": "The ones without a purl: not checked, and not clean.",
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ }
+ },
+ "required": [
+ "input",
+ "components_in_document",
+ "with_purl",
+ "without_purl",
+ "duplicates_removed",
+ "distinct_purls",
+ "batch_size",
+ "batches",
+ "batches_sent",
+ "sent",
+ "not_sent",
+ "not_sent_reason",
+ "rate_limit_waits",
+ "waited_ms",
+ "not_assessed",
+ "partial"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "error": {
+ "additionalProperties": false,
+ "properties": {
+ "kind": {
+ "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
+ "enum": [
+ "network",
+ "timeout",
+ "http",
+ "not_json",
+ "not_object",
+ "invalid_input",
+ "internal",
+ "unexpected_shape",
+ "radars"
+ ],
+ "type": "string"
+ },
+ "message": {
+ "description": "The cause: the API's own message, or what went wrong.",
+ "type": "string"
+ },
+ "path": {
+ "description": "The API path requested, when a request was made.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "status": {
+ "anyOf": [
+ {
+ "maximum": 9007199254740991,
+ "minimum": -9007199254740991,
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The HTTP status, when the API answered one."
+ }
+ },
+ "required": [
+ "kind",
+ "path",
+ "status",
+ "message"
+ ],
+ "type": "object"
+ },
+ "freshness": {
+ "type": "null"
+ },
+ "measured_at": {
+ "type": "null"
+ },
+ "method": {
+ "type": "null"
+ },
+ "notes": {
+ "description": "Caveats, one sentence each.",
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "state": {
+ "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
+ "enum": [
+ "failed",
+ "invalid_input"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "state",
+ "measured_at",
+ "method",
+ "coverage",
+ "freshness",
+ "notes",
+ "error"
+ ],
+ "type": "object"
+ }
+]