{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://github.com/welkaim/ea-codex/schemas/v1/rego-package.json",
  "title": "RegoPackage",
  "description": "Typed reference to a Rego policy package that mechanically enforces architectural decisions, principles, or standards. The Rego content itself lives in a separate policy repository; this artifact links the package to the Codex artifacts it enforces, surfaces its checkpoints (where in the pipeline or runtime the rules fire), and tracks its version. Closes the gap between a DecisionRecord's spec.doubleCheck.fitnessFunctions[] and the actual policy file in the policy repo.",
  "type": "object",
  "required": ["apiVersion", "kind", "metadata", "spec"],
  "properties": {
    "apiVersion": { "$ref": "_common.json#/$defs/apiVersion" },
    "kind": { "type": "string", "const": "RegoPackage" },
    "metadata": {
      "type": "object",
      "required": ["id", "name", "title", "status", "version"],
      "properties": {
        "id": { "$ref": "_common.json#/$defs/identifier" },
        "name": { "$ref": "_common.json#/$defs/slug" },
        "title": {
          "type": "string",
          "minLength": 3
        },
        "status": { "$ref": "_common.json#/$defs/lifecycleStatus" },
        "version": { "$ref": "_common.json#/$defs/version" },
        "owners": { "$ref": "_common.json#/$defs/owners" }
      },
      "additionalProperties": true
    },
    "spec": {
      "type": "object",
      "required": ["packageName", "repository", "checkPoints"],
      "properties": {
        "languageRef": {
          "type": "string",
          "enum": ["rego", "cedar", "cel", "sql", "graph-query", "test-harness"],
          "default": "rego",
          "description": "Policy language the package is written in. The kind is named RegoPackage for historical reasons (it was introduced when Rego was the only target); the languageRef field lets the kind also represent Cedar, CEL, SQL, or graph-query packages without renaming. v2 is expected to fold this kind into a more generic Control / PolicyPackage abstraction."
        },
        "packageName": {
          "type": "string",
          "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)*$",
          "description": "Package path as declared in the policy file (e.g., 'ea.sap.api_policy' for Rego). For non-Rego languages, use the language's natural namespace convention."
        },
        "repository": {
          "type": "string",
          "format": "uri",
          "description": "Git URL of the policy repository hosting the package."
        },
        "filePath": {
          "type": "string",
          "description": "Path to the .rego file within the repository."
        },
        "packageVersion": {
          "type": "string",
          "description": "Version or git tag of the package. Distinct from metadata.version (which versions the RegoPackage descriptor itself)."
        },
        "denyMode": {
          "type": "boolean",
          "description": "Whether the policy fails CI/runtime checks on violation (true) or only warns (false). Day-one deployments often use advisory mode for one or two sprints before flipping to deny."
        },
        "enforcedDecisions": {
          "type": "array",
          "description": "DecisionRecord identifiers this package enforces.",
          "items": { "$ref": "_common.json#/$defs/identifier" }
        },
        "enforcedStandards": {
          "type": "array",
          "description": "TechnologyStandard identifiers this package enforces.",
          "items": { "$ref": "_common.json#/$defs/identifier" }
        },
        "enforcedPrinciples": {
          "type": "array",
          "description": "ArchitecturePrinciple identifiers this package enforces.",
          "items": { "$ref": "_common.json#/$defs/identifier" }
        },
        "enforcedSemanticRules": {
          "type": "array",
          "description": "BusinessObject semantic-rule identifiers this package enforces. Format: '<BusinessObject-id>:<rule-id>' (e.g., 'BO-ADVERSE-EVENT:SR-AE-002'). Closes the loop from a Rego rule to the canonical semantic rule it implements.",
          "items": {
            "type": "string",
            "pattern": "^[A-Z][A-Z0-9-]*:[A-Z][A-Z0-9-]*$"
          }
        },
        "checkPoints": {
          "type": "array",
          "minItems": 1,
          "description": "Where and when the package is evaluated in the pipeline or at runtime.",
          "items": {
            "type": "object",
            "required": ["type", "scope"],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "ci-pull-request",
                  "ci-merge-gate",
                  "scheduled-scan",
                  "runtime-gateway",
                  "ea-tool-mcp-query",
                  "manual-review"
                ]
              },
              "trigger": {
                "type": "string",
                "description": "When this check fires (e.g., 'on every push', 'weekly', 'on every API call')."
              },
              "scope": {
                "type": "string",
                "description": "What artifacts or resources the check evaluates."
              }
            },
            "additionalProperties": true
          }
        },
        "entrypoints": {
          "type": "array",
          "description": "Named rule entrypoints in the Rego package and what each enforces.",
          "items": {
            "type": "object",
            "required": ["rule", "description"],
            "properties": {
              "rule": {
                "type": "string",
                "description": "Rule name in the package (e.g., 'allow', 'deny', 'violation')."
              },
              "description": { "type": "string" }
            },
            "additionalProperties": true
          }
        },
        "lastReviewDate": {
          "type": "string",
          "format": "date"
        }
      },
      "additionalProperties": true
    }
  },
  "additionalProperties": false
}
