{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://confighub.com/helm-expt/schemas/bundle-route.schema.json",
  "title": "Portable Bundle Route Intent",
  "description": "A companion artifact that travels inside a certified bundle and proposes handling for one quirk class named by the flattening-safety verdict. It records portable lifecycle knowledge at the base boundary. It is not the final destination route: a promotion or release must still bind the intent to an exact variant, destination, delivery runtime, checks, retry rule, failure rule, and receipt.",
  "type": "object",
  "required": [
    "apiVersion",
    "kind",
    "metadata",
    "spec"
  ],
  "additionalProperties": false,
  "properties": {
    "apiVersion": {
      "const": "evidence.confighub.com/v1alpha1"
    },
    "kind": {
      "const": "BundleRoute"
    },
    "metadata": {
      "type": "object",
      "required": [
        "name"
      ],
      "additionalProperties": false,
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "spec": {
      "type": "object",
      "required": [
        "quirkClass",
        "routeKind",
        "discharges",
        "declaration",
        "executedBy",
        "boundedness"
      ],
      "additionalProperties": false,
      "properties": {
        "quirkClass": {
          "description": "The flattening-safety quirk class this route discharges. It must match a disposition row in the receipt that ships the route.",
          "enum": [
            "helm-hooks",
            "resource-policy-keep",
            "lookup",
            "webhook-ca",
            "capabilities-api-versions",
            "generated-secrets",
            "crd-ordering",
            "immutable-fields",
            "namespace-creation",
            "subchart-conditions",
            "test-hooks"
          ]
        },
        "routeKind": {
          "enum": [
            "apply-ordering",
            "lifecycle-job",
            "prune-protection",
            "external-secret-reference",
            "versioned-replacement"
          ]
        },
        "discharges": {
          "description": "What breaks without this route, in one sentence.",
          "type": "string"
        },
        "declaration": {
          "description": "The route itself. Its shape depends on routeKind; apply-ordering carries ordered stages.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "stages": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "object",
                "required": [
                  "order",
                  "name",
                  "selector"
                ],
                "additionalProperties": false,
                "properties": {
                  "order": {
                    "type": "integer"
                  },
                  "name": {
                    "type": "string"
                  },
                  "selector": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "kinds": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "files": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "names": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "waitFor": {
                    "type": "string"
                  },
                  "objectCount": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "observedSyncWave": {
                    "description": "The Argo sync wave this stage was read back from, when the route restates an ordering the producer already declared rather than inventing one.",
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "executedBy": {
          "description": "Which runtimes could express this route intent, how each expresses it, and whether an exact run has been observed. The selected runtime is recorded later in a LifecycleRouteResolution.",
          "type": "object",
          "required": [
            "runtimes"
          ],
          "additionalProperties": false,
          "properties": {
            "runtimes": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "object",
                "required": [
                  "name",
                  "mechanism"
                ],
                "additionalProperties": false,
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "mechanism": {
                    "type": "string"
                  },
                  "proven": {
                    "type": "boolean",
                    "description": "True only when a runtime was watched executing this route. Preserving a declaration through delivery is not executing it."
                  },
                  "provenBy": {
                    "type": "string",
                    "description": "Repo-relative path to the receipt recording the run that proved it. Required whenever proven is true, so the claim can be opened rather than taken on trust."
                  }
                },
                "allOf": [
                  {
                    "if": {
                      "properties": {
                        "proven": {
                          "const": true
                        }
                      },
                      "required": [
                        "proven"
                      ]
                    },
                    "then": {
                      "required": [
                        "provenBy"
                      ]
                    }
                  }
                ]
              }
            },
            "automatic": {
              "description": "Whether this portable intent permits automatic execution after a destination-specific resolution selects a runtime and satisfies its checks. This flag is not execution proof; runtime.proven and a receipt record observed execution.",
              "type": "boolean"
            }
          }
        },
        "boundedness": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "provenance": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "emittedBy": {
              "type": "string"
            },
            "generatedFrom": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "verdictRef": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}
