{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:ohrisk:schema:common:3.5.0",
  "title": "Ohrisk report common definitions",
  "$defs": {
    "usageProfile": {
      "type": "string",
      "enum": [
        "saas",
        "distributed-app"
      ]
    },
    "riskSeverity": {
      "type": "string",
      "enum": [
        "low",
        "review",
        "high",
        "unknown"
      ]
    },
    "riskRecommendation": {
      "type": "string",
      "enum": [
        "allow",
        "review",
        "replace",
        "exclude-dev-only",
        "collect-evidence"
      ]
    },
    "riskDependencyType": {
      "type": "string",
      "enum": [
        "production",
        "development",
        "optional",
        "peer",
        "unknown"
      ]
    },
    "riskDependencyScope": {
      "type": "string",
      "enum": [
        "direct",
        "transitive"
      ]
    },
    "relativePath": {
      "type": "string",
      "minLength": 1,
      "pattern": "^(?![\\\\/])(?![A-Za-z]:[\\\\/])(?!\\.\\.(?:[\\\\/]|$))(?!.*[\\\\/]\\.\\.(?:[\\\\/]|$)).+$"
    },
    "nonNegativeInteger": {
      "type": "integer",
      "minimum": 0
    },
    "remoteRepository": {
      "type": "object",
      "required": [
        "owner",
        "name",
        "submodules",
        "symbolicLinks",
        "nonPortablePaths"
      ],
      "properties": {
        "owner": {
          "type": "string",
          "pattern": "^[A-Za-z0-9-]{1,39}$"
        },
        "name": {
          "type": "string",
          "pattern": "^[A-Za-z0-9._-]{1,100}$"
        },
        "submodules": {
          "type": "object",
          "required": [
            "mode",
            "skippedCount",
            "skippedPaths",
            "pathsTruncated"
          ],
          "properties": {
            "mode": {
              "type": "string",
              "enum": [
                "ignore",
                "reject"
              ]
            },
            "skippedCount": {
              "type": "integer",
              "minimum": 0,
              "maximum": 50000
            },
            "skippedPaths": {
              "type": "array",
              "maxItems": 100,
              "uniqueItems": true,
              "items": {
                "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/relativePath"
              }
            },
            "pathsTruncated": {
              "type": "boolean"
            }
          },
          "additionalProperties": false
        },
        "symbolicLinks": {
          "type": "object",
          "required": [
            "skippedCount",
            "skippedPaths",
            "pathsTruncated"
          ],
          "properties": {
            "skippedCount": {
              "type": "integer",
              "minimum": 0,
              "maximum": 50000
            },
            "skippedPaths": {
              "type": "array",
              "maxItems": 100,
              "uniqueItems": true,
              "items": {
                "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/relativePath"
              }
            },
            "pathsTruncated": {
              "type": "boolean"
            }
          },
          "additionalProperties": false
        },
        "nonPortablePaths": {
          "type": "object",
          "required": [
            "skippedCount",
            "skippedPaths",
            "pathsTruncated"
          ],
          "properties": {
            "skippedCount": {
              "type": "integer",
              "minimum": 0,
              "maximum": 50000
            },
            "skippedPaths": {
              "type": "array",
              "maxItems": 100,
              "uniqueItems": true,
              "items": {
                "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/relativePath"
              }
            },
            "pathsTruncated": {
              "type": "boolean"
            }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    },
    "lockfile": {
      "type": "object",
      "required": [
        "kind",
        "path"
      ],
      "properties": {
        "kind": {
          "type": "string",
          "minLength": 1
        },
        "path": {
          "type": "string",
          "minLength": 1,
          "pattern": "^(?![\\\\/])(?![A-Za-z]:[\\\\/])(?!\\.\\.(?:[\\\\/]|$))(?!.*[\\\\/]\\.\\.(?:[\\\\/]|$)).+$"
        }
      },
      "additionalProperties": false
    },
    "riskFinding": {
      "type": "object",
      "required": [
        "id",
        "fingerprint",
        "packageId",
        "severity",
        "reason",
        "action",
        "dependencyType",
        "dependencyScope",
        "evidence",
        "paths",
        "recommendation"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "fingerprint": {
          "type": "string",
          "minLength": 1
        },
        "packageId": {
          "type": "string",
          "minLength": 1
        },
        "severity": {
          "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/riskSeverity"
        },
        "reason": {
          "type": "string",
          "minLength": 1
        },
        "action": {
          "type": "string",
          "minLength": 1
        },
        "dependencyType": {
          "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/riskDependencyType"
        },
        "dependencyScope": {
          "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/riskDependencyScope"
        },
        "evidence": {
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1
          }
        },
        "paths": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "minLength": 1
            }
          }
        },
        "recommendation": {
          "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/riskRecommendation"
        }
      },
      "additionalProperties": false
    },
    "riskWaiver": {
      "type": "object",
      "required": [
        "reason"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "fingerprint": {
          "type": "string",
          "minLength": 1
        },
        "reason": {
          "type": "string",
          "minLength": 1
        },
        "expiresOn": {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        }
      },
      "anyOf": [
        {
          "required": [
            "id"
          ]
        },
        {
          "required": [
            "fingerprint"
          ]
        }
      ],
      "additionalProperties": false
    },
    "waivedRiskFinding": {
      "type": "object",
      "required": [
        "finding",
        "waiver",
        "matchedBy"
      ],
      "properties": {
        "finding": {
          "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/riskFinding"
        },
        "waiver": {
          "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/riskWaiver"
        },
        "matchedBy": {
          "type": "string",
          "enum": [
            "id",
            "fingerprint"
          ]
        }
      },
      "additionalProperties": false
    },
    "normalizedLicense": {
      "type": "object",
      "required": [
        "packageId",
        "choices",
        "joiner",
        "signals",
        "evidenceSources",
        "confidence"
      ],
      "properties": {
        "packageId": {
          "type": "string",
          "minLength": 1
        },
        "original": {
          "type": "string"
        },
        "expression": {
          "type": "string",
          "minLength": 1
        },
        "choices": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "string",
            "minLength": 1
          }
        },
        "joiner": {
          "type": "string",
          "enum": [
            "single",
            "and",
            "or",
            "mixed"
          ]
        },
        "signals": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "string",
            "enum": [
              "missing",
              "malformed",
              "conflicting-evidence",
              "custom-text",
              "commercial-restriction",
              "notice-required"
            ]
          }
        },
        "evidenceSources": {
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1
          }
        },
        "confidence": {
          "type": "string",
          "enum": [
            "high",
            "medium",
            "low"
          ]
        },
        "exceptions": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "string",
            "minLength": 1
          }
        }
      },
      "additionalProperties": false
    },
    "policySummary": {
      "type": "object",
      "required": [
        "digest",
        "enabled",
        "sourceFiles",
        "allowLicenseCount",
        "denyLicenseCount",
        "severityOverrideCount",
        "packageRuleCount",
        "profileCount",
        "profileOverrideCount",
        "allowedRegistryHostCount",
        "registryAuthHostCount"
      ],
      "properties": {
        "digest": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$"
        },
        "enabled": {
          "type": "boolean"
        },
        "sourceFiles": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/relativePath"
          }
        },
        "allowLicenseCount": {
          "type": "integer",
          "minimum": 0
        },
        "denyLicenseCount": {
          "type": "integer",
          "minimum": 0
        },
        "severityOverrideCount": {
          "type": "integer",
          "minimum": 0
        },
        "packageRuleCount": {
          "type": "integer",
          "minimum": 0
        },
        "profileCount": {
          "type": "integer",
          "minimum": 0
        },
        "profileOverrideCount": {
          "type": "integer",
          "minimum": 0
        },
        "allowedRegistryHostCount": {
          "type": "integer",
          "minimum": 0
        },
        "registryAuthHostCount": {
          "type": "integer",
          "minimum": 0
        },
        "npmRegistryUrl": {
          "type": "string",
          "pattern": "^https://",
          "minLength": 9
        }
      },
      "additionalProperties": false
    },
    "riskCounts": {
      "type": "object",
      "required": [
        "high",
        "review",
        "unknown",
        "low"
      ],
      "properties": {
        "high": {
          "type": "integer",
          "minimum": 0
        },
        "review": {
          "type": "integer",
          "minimum": 0
        },
        "unknown": {
          "type": "integer",
          "minimum": 0
        },
        "low": {
          "type": "integer",
          "minimum": 0
        }
      },
      "additionalProperties": false
    },
    "dependencyGraphCounts": {
      "type": "object",
      "required": [
        "total",
        "direct",
        "transitive"
      ],
      "properties": {
        "total": {
          "type": "integer",
          "minimum": 0
        },
        "direct": {
          "type": "integer",
          "minimum": 0
        },
        "transitive": {
          "type": "integer",
          "minimum": 0
        }
      },
      "additionalProperties": false
    },
    "dependencyGraphDiagnostic": {
      "type": "object",
      "required": [
        "code",
        "affectedNodeCount",
        "limit",
        "message"
      ],
      "properties": {
        "code": {
          "type": "string",
          "enum": [
            "dependency_paths_truncated",
            "dependency_path_depth_summarized"
          ]
        },
        "affectedNodeCount": {
          "type": "integer",
          "minimum": 1
        },
        "limit": {
          "type": "integer",
          "minimum": 1
        },
        "message": {
          "type": "string",
          "minLength": 1
        }
      },
      "additionalProperties": false
    },
    "evidenceSourceCounts": {
      "type": "object",
      "required": [
        "packages",
        "files",
        "warnings"
      ],
      "properties": {
        "packages": {
          "type": "integer",
          "minimum": 0
        },
        "files": {
          "type": "integer",
          "minimum": 0
        },
        "warnings": {
          "type": "integer",
          "minimum": 0
        }
      },
      "additionalProperties": false
    },
    "evidenceDiagnostic": {
      "type": "object",
      "required": [
        "code",
        "source",
        "packageCount",
        "occurrenceCount"
      ],
      "properties": {
        "code": {
          "type": "string",
          "enum": [
            "collector_warning",
            "license_evidence_missing",
            "source_unavailable"
          ]
        },
        "source": {
          "type": "string",
          "enum": [
            "local",
            "registry",
            "sbom",
            "tarball",
            "unavailable"
          ]
        },
        "packageCount": {
          "type": "integer",
          "minimum": 1
        },
        "occurrenceCount": {
          "type": "integer",
          "minimum": 1
        }
      },
      "additionalProperties": false
    },
    "evidenceCounts": {
      "type": "object",
      "required": [
        "packages",
        "files",
        "warnings",
        "sources",
        "diagnostics"
      ],
      "properties": {
        "packages": {
          "type": "integer",
          "minimum": 0
        },
        "files": {
          "type": "integer",
          "minimum": 0
        },
        "warnings": {
          "type": "integer",
          "minimum": 0
        },
        "sources": {
          "type": "object",
          "required": [
            "local",
            "registry",
            "sbom",
            "tarball",
            "unavailable"
          ],
          "properties": {
            "local": {
              "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/evidenceSourceCounts"
            },
            "registry": {
              "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/evidenceSourceCounts"
            },
            "sbom": {
              "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/evidenceSourceCounts"
            },
            "tarball": {
              "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/evidenceSourceCounts"
            },
            "unavailable": {
              "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/evidenceSourceCounts"
            }
          },
          "additionalProperties": false
        },
        "diagnostics": {
          "type": "array",
          "items": {
            "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/evidenceDiagnostic"
          }
        }
      },
      "additionalProperties": false
    },
    "licenseCounts": {
      "type": "object",
      "required": [
        "highConfidence",
        "mediumConfidence",
        "lowConfidence",
        "missing",
        "malformed"
      ],
      "properties": {
        "highConfidence": {
          "type": "integer",
          "minimum": 0
        },
        "mediumConfidence": {
          "type": "integer",
          "minimum": 0
        },
        "lowConfidence": {
          "type": "integer",
          "minimum": 0
        },
        "missing": {
          "type": "integer",
          "minimum": 0
        },
        "malformed": {
          "type": "integer",
          "minimum": 0
        }
      },
      "additionalProperties": false
    },
    "waiverCounts": {
      "type": "object",
      "required": [
        "applied",
        "expired",
        "unmatched"
      ],
      "properties": {
        "applied": {
          "type": "integer",
          "minimum": 0
        },
        "expired": {
          "type": "integer",
          "minimum": 0
        },
        "unmatched": {
          "type": "integer",
          "minimum": 0
        }
      },
      "additionalProperties": false
    },
    "packageProvenance": {
      "type": "object",
      "required": [
        "packageId",
        "purl",
        "origins"
      ],
      "properties": {
        "packageId": {
          "type": "string",
          "minLength": 1
        },
        "purl": {
          "type": "string",
          "pattern": "^pkg:",
          "minLength": 5
        },
        "origins": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/lockfile"
          }
        }
      },
      "additionalProperties": false
    },
    "lockfileChanges": {
      "type": "object",
      "required": [
        "current",
        "baseline",
        "added",
        "removed"
      ],
      "properties": {
        "current": {
          "type": "array",
          "items": {
            "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/lockfile"
          }
        },
        "baseline": {
          "type": "array",
          "items": {
            "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/lockfile"
          }
        },
        "added": {
          "type": "array",
          "items": {
            "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/lockfile"
          }
        },
        "removed": {
          "type": "array",
          "items": {
            "$ref": "urn:ohrisk:schema:common:3.5.0#/$defs/lockfile"
          }
        }
      },
      "additionalProperties": false
    }
  }
}
