{
  "description": "Auto-generated derived type for SnapshotSpec via `CustomResource`",
  "properties": {
    "spec": {
      "additionalProperties": false,
      "description": "A single kopia snapshot represented as a Kubernetes object. ADR §3.4.\n\nFor `scheduled`/`manual` backups the spec carries `policyRef` (+ optional\noverrides). For `discovered` backups the spec is empty — every field is optional.",
      "properties": {
        "deletionPolicy": {
          "description": "Lifecycle of the underlying kopia snapshot when its `Snapshot` CR is deleted.\nShared by `SnapshotPolicy.spec.defaultDeletionPolicy` and `Snapshot.spec.deletionPolicy`.\nADR-0003 §4.5 / ADR-0001 §4.5.\n\nThe reconciler distinguishes the three cases with an exhaustive `match` — Rust\nenforces that any new variant added later must be handled in every match site,\npreventing the class of bug where a new policy slips into production without a\ncorresponding reconcile branch.\n\n```\nuse kopiur_api::common::DeletionPolicy;\n\n// Produced backups default to deleting the snapshot with the CR.\nassert_eq!(DeletionPolicy::default(), DeletionPolicy::Delete);\n// Variants serialize to their bare PascalCase names (plain string enum).\nassert_eq!(serde_json::to_value(DeletionPolicy::Retain).unwrap(), \"Retain\");\nassert_eq!(serde_json::to_value(DeletionPolicy::Orphan).unwrap(), \"Orphan\");\n```",
          "enum": [
            "Delete",
            "Retain",
            "Orphan"
          ],
          "nullable": true,
          "type": [
            "string",
            "null"
          ]
        },
        "failurePolicy": {
          "additionalProperties": false,
          "description": "Per-run failure controls passed to the mover `Job`. ADR §3.4 (G6).",
          "nullable": true,
          "properties": {
            "activeDeadlineSeconds": {
              "description": "Passed through to the mover `Job.spec.activeDeadlineSeconds` — wall-clock cap\nafter which a still-running run is killed.",
              "format": "int64",
              "nullable": true,
              "type": [
                "integer",
                "null"
              ]
            },
            "backoffLimit": {
              "description": "Passed through to the mover `Job.spec.backoffLimit` — how many times a failed\nrun is retried before the Job is marked failed.",
              "format": "int32",
              "nullable": true,
              "type": [
                "integer",
                "null"
              ]
            }
          },
          "type": [
            "object",
            "null"
          ]
        },
        "pin": {
          "description": "Pin this snapshot to exempt it from GFS retention (ADR-0005 §13(c)). When\n`true` the reconciler applies a kopia snapshot pin and the GFS pruner never\nselects it for deletion — for pre-migration / compliance holds. Clearing it\nremoves the pin. Default `false`.",
          "type": [
            "boolean",
            "null"
          ]
        },
        "policyRef": {
          "additionalProperties": false,
          "description": "The recipe to run. Absent for `discovered` backups. ADR §3.4.",
          "nullable": true,
          "properties": {
            "name": {
              "description": "Name of the referenced `SnapshotPolicy`.",
              "type": "string"
            },
            "namespace": {
              "description": "Namespace of the `SnapshotPolicy`; absent = same namespace as the referrer.",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            }
          },
          "required": [
            "name"
          ],
          "type": [
            "object",
            "null"
          ]
        },
        "tags": {
          "additionalProperties": {
            "type": "string"
          },
          "description": "Arbitrary kopia snapshot tags (e.g. `reason: scheduled-nightly`). ADR §3.4.",
          "nullable": true,
          "type": [
            "object",
            "null"
          ]
        }
      },
      "type": "object"
    },
    "status": {
      "additionalProperties": false,
      "description": "Observed state of a [`Snapshot`]. ADR §3.4 status.",
      "nullable": true,
      "properties": {
        "conditions": {
          "description": "Standard Kubernetes conditions (e.g. `SourcesQuiesced`, `SnapshotCreated`).\nADR §3.4 status.",
          "items": {
            "additionalProperties": false,
            "description": "Condition contains details for one aspect of the current state of this API Resource.",
            "properties": {
              "lastTransitionTime": {
                "description": "lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.",
                "format": "date-time",
                "type": "string"
              },
              "message": {
                "description": "message is a human readable message indicating details about the transition. This may be an empty string.",
                "type": "string"
              },
              "observedGeneration": {
                "description": "observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.",
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "reason": {
                "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.",
                "type": "string"
              },
              "status": {
                "description": "status of the condition, one of True, False, Unknown.",
                "type": "string"
              },
              "type": {
                "description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
                "type": "string"
              }
            },
            "required": [
              "lastTransitionTime",
              "message",
              "reason",
              "status",
              "type"
            ],
            "type": "object"
          },
          "type": [
            "array",
            "null"
          ]
        },
        "failure": {
          "additionalProperties": false,
          "description": "Structured terminal-failure detail (kopia error class, stderr tail, retry\nhint), written by the mover before it exits non-zero. ADR §4.10.",
          "nullable": true,
          "properties": {
            "exitCode": {
              "description": "The process exit code, if one was reported.",
              "format": "int32",
              "nullable": true,
              "type": [
                "integer",
                "null"
              ]
            },
            "kopiaErrorClass": {
              "description": "kopia error class (e.g. `RepositoryUnavailable`, `AuthFailure`).",
              "type": "string"
            },
            "message": {
              "description": "A short human-readable message: what failed, why, and how to fix it.",
              "type": "string"
            },
            "retryRecommended": {
              "description": "Whether retrying the same operation unchanged could succeed.",
              "type": "boolean"
            },
            "stderrTail": {
              "description": "The last lines of kopia's stderr, if any were captured (bounded by\n[`MAX_LOG_TAIL_BYTES`]).",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            }
          },
          "required": [
            "kopiaErrorClass",
            "message",
            "retryRecommended"
          ],
          "type": [
            "object",
            "null"
          ]
        },
        "hooks": {
          "additionalProperties": false,
          "description": "Hook-execution bookkeeping (ADR §4.8): completion timestamps the\nreconciler stamps so each hook list runs exactly once per Snapshot across\nrequeues and controller restarts (hooks have side effects — quiesce,\nresume — that must not repeat).",
          "nullable": true,
          "properties": {
            "postCompletedAt": {
              "description": "When the `afterSnapshot` list completed (RFC3339); absent until it has.",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            },
            "preCompletedAt": {
              "description": "When the `beforeSnapshot` list completed (RFC3339); absent until it has.",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            }
          },
          "type": [
            "object",
            "null"
          ]
        },
        "job": {
          "additionalProperties": false,
          "description": "Present for scheduled/manual; absent for discovered. ADR §3.4.",
          "nullable": true,
          "properties": {
            "attempts": {
              "description": "Number of attempts so far (bounded by `failurePolicy.backoffLimit`). ADR §3.4 status.",
              "format": "int32",
              "nullable": true,
              "type": [
                "integer",
                "null"
              ]
            },
            "name": {
              "description": "Name of the mover `Job`. ADR §3.4 status.",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            }
          },
          "type": [
            "object",
            "null"
          ]
        },
        "logTail": {
          "description": "The last lines of the run's output, written by the mover at the terminal\ntransition (success: the `Snapshot created: \u003cid\u003e` line; failure: the\nactionable error + kopia stderr tail). Capped at\n[`crate::common::MAX_LOG_TAIL_BYTES`]; full logs live in the Job pod.\nADR §3.4/§4.10.",
          "nullable": true,
          "type": [
            "string",
            "null"
          ]
        },
        "observedGeneration": {
          "description": "`metadata.generation` last reconciled, for staleness detection. ADR §3.4 status.",
          "format": "int64",
          "nullable": true,
          "type": [
            "integer",
            "null"
          ]
        },
        "origin": {
          "description": "How a `Snapshot` came to exist. Canonical value mirrored from the `kopiur.home-operations.com/origin`\nlabel. Closed enum. ADR §3.4.\n\nOrigin drives the deletion-policy default (ADR §4.5): `discovered` backups are\nforced to `Retain` because the operator did not create those snapshots.\n\n```\nuse kopiur_api::Origin;\n\nassert_eq!(Origin::default(), Origin::Scheduled);\n// Serializes camelCase, matching the `origin` label/status value.\nassert_eq!(serde_json::to_value(Origin::Discovered).unwrap(), \"discovered\");\n```",
          "enum": [
            "scheduled",
            "manual",
            "discovered"
          ],
          "nullable": true,
          "type": [
            "string",
            "null"
          ]
        },
        "phase": {
          "description": "Lifecycle phase of a `Snapshot`. Closed enum. ADR §3.4 status.\n\n```\nuse kopiur_api::{SnapshotPhase, PhaseLabel};\n\nassert_eq!(SnapshotPhase::default(), SnapshotPhase::Pending);\n// `PhaseLabel::label` gives the stable string used in status/metrics.\nassert_eq!(SnapshotPhase::Succeeded.label(), \"Succeeded\");\n// Every variant is enumerated for metric reset.\nassert_eq!(SnapshotPhase::ALL.len(), 6);\n```",
          "enum": [
            "Pending",
            "Running",
            "Succeeded",
            "Failed",
            "Deleting",
            "Discovered"
          ],
          "nullable": true,
          "type": [
            "string",
            "null"
          ]
        },
        "pinned": {
          "description": "The observed kopia-side pin state (ADR-0005 §13(c)): `Some(true)` once the\noperator has applied the pin, `Some(false)` once it has removed it, `None`\nbefore any pin reconcile. The reconciler compares `spec.pin` against this to\ndecide whether to issue a `kopia snapshot pin`/`unpin`, so a redundant op is\nnever spawned.",
          "nullable": true,
          "type": [
            "boolean",
            "null"
          ]
        },
        "resolved": {
          "additionalProperties": false,
          "description": "Frozen recipe values at run time (scheduled/manual). ADR §3.4.",
          "nullable": true,
          "properties": {
            "repository": {
              "additionalProperties": false,
              "description": "The repository this run targeted, frozen at run time. ADR §3.4 status.",
              "nullable": true,
              "properties": {
                "kind": {
                  "default": "Repository",
                  "description": "Which repository CRD this points at; defaults to [`RepositoryKind::Repository`].",
                  "enum": [
                    "Repository",
                    "ClusterRepository"
                  ],
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "name": {
                  "description": "Name of the referenced `Repository`/`ClusterRepository`.",
                  "type": "string"
                },
                "namespace": {
                  "description": "Cross-namespace `Repository` reference; ignored/forbidden for `ClusterRepository`.",
                  "nullable": true,
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "name"
              ],
              "type": [
                "object",
                "null"
              ]
            },
            "sources": {
              "description": "The concrete PVCs + source paths backed up this run. ADR §3.4 status.",
              "items": {
                "additionalProperties": false,
                "description": "One resolved source backed up by a run — a concrete PVC and its kopia path. ADR §3.4 status.",
                "properties": {
                  "pvc": {
                    "description": "`namespace/name` of the PVC, as kopia sees it. ADR §3.4.",
                    "nullable": true,
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "sourcePath": {
                    "description": "The source path kopia recorded for this PVC. ADR §3.4/§4.2.",
                    "nullable": true,
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "type": "object"
              },
              "type": [
                "array",
                "null"
              ]
            }
          },
          "type": [
            "object",
            "null"
          ]
        },
        "snapshot": {
          "additionalProperties": false,
          "description": "The kopia artifact this CR represents. ADR §3.4.",
          "nullable": true,
          "properties": {
            "identity": {
              "additionalProperties": false,
              "description": "The `username@hostname:path` identity recorded for this snapshot. ADR §3.4/§4.2.",
              "properties": {
                "hostname": {
                  "description": "The final `hostname` kopia records, fixed at admission.",
                  "type": "string"
                },
                "sourcePath": {
                  "description": "The resolved snapshot source path, when applicable (`username@hostname:path`).",
                  "nullable": true,
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "username": {
                  "description": "The final `username` kopia records, fixed at admission.",
                  "type": "string"
                }
              },
              "required": [
                "hostname",
                "username"
              ],
              "type": "object"
            },
            "kopiaSnapshotID": {
              "description": "kopia's snapshot ID — the handle the finalizer uses to delete content.\n\nRenamed to match the ADR wire shape exactly (`kopiaSnapshotID`, capital `ID`);\nserde's `camelCase` would otherwise produce `kopiaSnapshotId`.",
              "type": "string"
            }
          },
          "required": [
            "identity",
            "kopiaSnapshotID"
          ],
          "type": [
            "object",
            "null"
          ]
        },
        "staged": {
          "additionalProperties": false,
          "description": "The CSI staging objects the run created for `copyMethod: Snapshot`/`Clone`\n(ADR §3.3). Pinned once when the stage is provisioned so the reconciler can\n(a) reuse the same VolumeSnapshot/PVC across mover-Job retries idempotently\nand (b) reap them on the terminal transition. Absent for `Direct` (and NFS),\nwhich mount the live source with no staging.",
          "nullable": true,
          "properties": {
            "copyMethod": {
              "description": "The resolved capture method (`Snapshot` or `Clone`) that produced this stage.",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            },
            "pvcName": {
              "description": "Name of the staged `PersistentVolumeClaim` the mover mounts in place of the\nlive source PVC.",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            },
            "ready": {
              "description": "`true` once the stage is ready for the mover (VolumeSnapshot `readyToUse` and\nthe staged PVC applied). Before that the reconcile is still provisioning it.",
              "nullable": true,
              "type": [
                "boolean",
                "null"
              ]
            },
            "volumeSnapshotName": {
              "description": "Name of the `VolumeSnapshot` created from the source PVC (`copyMethod: Snapshot`\nonly; absent for `Clone`, which stages directly from the source PVC).",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            }
          },
          "type": [
            "object",
            "null"
          ]
        },
        "stats": {
          "additionalProperties": false,
          "description": "Byte/file counts parsed from kopia's JSON output. ADR §3.4 status.",
          "nullable": true,
          "properties": {
            "bytesNew": {
              "description": "Bytes newly uploaded this run (after dedup/compression). ADR §3.4 status.",
              "format": "int64",
              "nullable": true,
              "type": [
                "integer",
                "null"
              ]
            },
            "filesModified": {
              "description": "Count of files changed since the previous snapshot. ADR §3.4 status.",
              "format": "int64",
              "nullable": true,
              "type": [
                "integer",
                "null"
              ]
            },
            "filesNew": {
              "description": "Count of files new since the previous snapshot. ADR §3.4 status.",
              "format": "int64",
              "nullable": true,
              "type": [
                "integer",
                "null"
              ]
            },
            "filesUnchanged": {
              "description": "Count of files unchanged since the previous snapshot. ADR §3.4 status.",
              "format": "int64",
              "nullable": true,
              "type": [
                "integer",
                "null"
              ]
            },
            "sizeBytes": {
              "description": "Total logical size of the snapshot in bytes. ADR §3.4 status.",
              "format": "int64",
              "nullable": true,
              "type": [
                "integer",
                "null"
              ]
            }
          },
          "type": [
            "object",
            "null"
          ]
        },
        "timing": {
          "additionalProperties": false,
          "description": "Start/end/duration of the snapshot run. ADR §3.4 status.",
          "nullable": true,
          "properties": {
            "durationSeconds": {
              "description": "Wall-clock duration in seconds. ADR §3.4 status.",
              "format": "int64",
              "nullable": true,
              "type": [
                "integer",
                "null"
              ]
            },
            "endTime": {
              "description": "RFC3339 end time of the run. ADR §3.4 status.",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            },
            "startTime": {
              "description": "RFC3339 start time of the run. ADR §3.4 status.",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            }
          },
          "type": [
            "object",
            "null"
          ]
        }
      },
      "type": [
        "object",
        "null"
      ]
    }
  },
  "required": [
    "spec"
  ],
  "title": "Snapshot",
  "type": "object"
}